jeremyevans/roda

Add an example of how to set up code reloading to README.md

akxcv opened this issue · 5 comments

akxcv commented

Hi Jeremy!

Recently, I was playing around with building a simple application with Roda, and I found myself scratching my head a little on how to set up code reloading.

I know you have some notes on that in the README, but I thought it would be a good idea to provide a small code sample that would make code reloading work.

In my setup, I'm using listen and zeitwerk.

# config.ru

require 'bundler/setup'
require 'zeitwerk'
require 'listen'

loader = Zeitwerk::Loader.new
loader.push_dir(File.join(__dir__, 'app'))
loader.enable_reloading
loader.setup

listener = Listen.to(File.join(__dir__, 'app')) do |_modified, _added, _removed|
  loader.reload
end
listener.start

# ... setup roda and etc

run App.freeze.run

I thought it would be useful to provide such an example in the README. I'm willing to open a pull request if you think this is a good idea.

I don't want to provide a example, because there are six code reloading libraries discussed in the README, and it doesn't make sense to provide an example for only one.

One issue with Zeitwork for Roda is that it doesn't handle one class split into multiple files, unless support for that has been added to Zeitwork since I last looked at it. That is common in Roda apps using the hash_routes or multi_route plugins.

I do think it would be good to update the README to replace ActiveSupport::Dependencies with Zeitwork. Could you send a PR for that?

akxcv commented

Sure, I'll try to submit a PR if I have time (probably need to learn more about potential peculiarities of Zeitwerk).

hey @akxcv, sorry to ping you on this closed issue but do you remember how exactly did you setup zeitwerk to work with Roda? I have the exact same code as you but reloading does nothing. I think maybe it's some sort of voodoo with your App.freeze.run? I'm using App.freeze.app, so what's up with that?

akxcv commented

hey @unleashy, I'm not sure, but I'm calling a custom Router class inside my Roda app. This router class gets reloaded by Zeitwerk, maybe that's required for reloading to work. Or, maybe, you'll need to place your Roda app itself somewhere in the scope of reloadable files. Could you try that and see if it works?

@akxcv Yeah, the router was in the scope of reloadable files but the constant wasn't, since zeitwerk wouldn't reload a config.ru; what I did was to create a simple rack server like this, in a file reloadable by zeitwerk:

module ReloadableServer
  def self.call(env)
    app.call(env)
  end

  def self.app
    App.freeze.app
  end
end

and use run ReloadableServer instead of run App.freeze.app. It works, although it's probably inefficient since the app is re-evaluated on every request. I tried caching it with an instance variable but that didn't work. Oh well!