rails-dev-boost icon indicating copy to clipboard operation
rails-dev-boost copied to clipboard

Constant unloaded but not using latest version after refresh

Open frobichaud opened this issue 10 years ago • 3 comments

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?

frobichaud avatar Apr 29 '15 02:04 frobichaud

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!

thedarkone avatar May 06 '15 18:05 thedarkone

ping @frobichaud, any chance you had a look at this?

thedarkone avatar Jul 02 '15 23:07 thedarkone

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

frobichaud avatar Jan 07 '16 13:01 frobichaud