cronokirby/alchemy

Runtime loading of cogs

Opened this issue · 6 comments

Atm, I don't see a way to start a Cog at runtime. I would like to be able to unload a cog, then load a replacement as needed. Main reasons for this are hotfixes and inconsequential updates that shouldn't necessitate a redeploy.

Calling https://hexdocs.pm/discord_alchemy/0.6.0/Alchemy.Cogs.html#unload/1, then reloading the module in iex, and then calling use Cog again should work, iirc.

But that would restart the whole bot, would it not?

You just need to reload the Cog module, I was a bit unclear. You can do that while keeping the rest of the bot running.

Huh, nice! I would suggest making it a little more clear in the docs that Cogs load themselves into the Client on module load.

Yeah use is a bit magical in general: https://elixir-lang.org/getting-started/alias-require-and-import.html#use
But basically it runs code defined in the Cog module you've created. And by using Cogs.def and the other macro, you're defining what code is going to be in that startup function. Then when you call use Cog, it uses that startup function to register all the command handlers you've defined in that Cog.

Strictly speaking, if you don't change the arity of any of your Cog functions / command handlers, or add new handlers you don't even need to call Cogs.unload, since the function references will be valid, and elixir's hot reloading mechanism will mean that the functions will point to the new ones as soon as the module is reloaded.

use Cog is needed whenever you've introduced new commands, and need to register those as well. You usually want to call Cogs.unload prior to this, to make sure you don't have stale references to functions that don't exist anymore though.

TLDR reloading the Cog module in the repl, calling Cogs.unload and then running use Cog will always work.

The docs could use a section explaining how to hot reload things, it definitely isn't super clear atm...

That makes everything clear, thank you!