rails-dev-boost
rails-dev-boost copied to clipboard
Constant unloaded but not using latest version after refresh
Hi, I'm using Grape to serve an API with Rails 4 and my config looks like this: application.rb: config.paths.add File.join('app', 'api'), glob: File.join('', '.rb') config.autoload_paths += Dir[Rails.root.join('app', 'api', '')]
My project structure is
app/
api/
base_api.rb
v1/
notification_api.rb
We mount grape in routes.rb as follow:
mount BaseApi => '/api'
When debugging rails-dev-boost, I can see notification_api.rb being loaded in the constants. If I modify the file, and perform another request, the debug! shows:
[DEV-BOOST] --- START ---
[DEV-BOOST] [CHANGED] #<LoadedFile /app/api/v1/notification_api.rb [V1::NotificationApi]>
[DEV-BOOST] [SCHEDULE_DEPENDENT] #<LoadedFile /app/api/v1/notification_api.rb [V1::NotificationApi]>: #<LoadedFile /config/routes.rb []>
[DEV-BOOST] [SCHEDULE_REMOVAL | SCHEDULED] V1::NotificationApi
[DEV-BOOST] [SCHEDULE_CONTAINING_FILE] V1::NotificationApi -> #<LoadedFile /app/api/v1/notification_api.rb [V1::NotificationApi]>
[DEV-BOOST] [REMOVE_CONST] V1::NotificationApi
[DEV-BOOST] --- END ---
But the code being executed is still the old one. I debugged the gem and went through the code where my constant was removed.
If I perform a second modification and another request, the constant is not loaded, and debug! shows:
[DEV-BOOST] --- START ---
[DEV-BOOST] --- END ---
So it looks like my NotificationApi is autoloaded fine at the start, it is unloaded on the first modification but never reloaded again.
@thedarkone, can you see something wrong in my setup?
Hey @frobichaud,
thanks for reporting this.
I'm reasonably certain your issue stems from Rails routes keeping a reference to a now stale BaseApi/V1::NotificationApi. In short, the problem is that rails-dev-boost fails to detect routes.rb -> V1::NotificationApi dependency. Normally the detection works like this: when a routes.rb is being executed any new constant auto-loading events are detected (ie: your routes.rb would trigger the autoloading of BaseApi/V1::NotificationApi).
The detection mechanism is fragile and will not work, if for example BaseApi/V1::NotificationApi constants are autoloaded prior to the first execution of a routes.rb (for example if you access those constants in application.rb or in general in an config/initializers file) file the dependency link would not be established.
Rails itself deals with this problem by re-evaluating routes.rb on every "file-changing" request, rails-dev-boost disables this behavior (as it slows down dev mode, especially for apps with huge routes.rb files), see the readme: https://github.com/thedarkone/rails-dev-boost#routesrb-potentially-not-reloading. There is config option to make rails-dev-boost behave as Rails does (RailsDevelopmentBoost.reload_routes_on_any_change = true), you can try that see if it helps with your problem.
Can you also try this new branch routes-and-boot-time-consts that tries to improve on routes.rb -> const detection?
gem 'rails-dev-boost', :github => 'thedarkone/rails-dev-boost', :branch => 'routes-and-boot-time-consts'
Please report back if the branch or the flag toggle helps!
ping @frobichaud, any chance you had a look at this?
@thedarkone I finally got the chance to try all your propositions but I had no luck. My API code does not reload on change. I'll try to dig even further.