alchemy icon indicating copy to clipboard operation
alchemy copied to clipboard

Runtime loading of cogs

Open khionu opened this issue 5 years ago • 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.

khionu avatar May 14 '20 15:05 khionu

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.

cronokirby avatar May 14 '20 15:05 cronokirby

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

khionu avatar May 14 '20 16:05 khionu

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.

cronokirby avatar May 14 '20 17:05 cronokirby

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

khionu avatar May 14 '20 17:05 khionu

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...

cronokirby avatar May 14 '20 17:05 cronokirby

That makes everything clear, thank you!

khionu avatar May 14 '20 17:05 khionu