Dry-system, zeitwerk and code reloading

I finally got around to play with dry-system 0.19. Since I haven’t used Zeitwerk before, I tried using just Zeitwerk and Roda to see if the code reloading works. That part was relatively easy to get to work.
But then I wanted to add dry-system into the mix, and so far, all my efforts to have code reloading work in development have failed. The furthest I have come is getting a Nothing registered with the key error after the code gets reloaded.

I think this is because I am using a boot file to register the Roda app, since auto-registering doesn’t play nice with Roda.

I put up the simplest setup that reproduces the problem here. What I find interesting is that after the code reloads, the auto-registered key “foo” exists, but “reload_app” is nowhere to be found. Is this expected behaviour, or is this a bug?

Okay, so after digging around a bit more, I have found a solution. The problem was that the files in ‘system/boot’ were still required, so after a reload, they were not required again.

To get around this, we have to use Zeitwerk’s on_load hook:

::Loader.on_load('Container') do |_foo|
  $LOADED_FEATURES.reject! { |path| path =~ %r{/system/boot/} }
end

This will invalidate all the files in system/boot and everything will work as expected, as can be seen in this branch.

2 Likes

Thanks for persisting with this, @rickenharp, and for sharing your solution!

Now that we have another key abstraction falling into place with namespaces, I think we’re close to the point now that we could have a simple use :zeitwerk plugin for dry-system. Once we get to that point, we could probably think about internal reloading (my instinct would be to ship a plugin explicitly without reloading first), and your discovery about the boot files will be important for making that happen.