Skip to content

Enable code reloading in development mode with Rails 5#2457

Merged
mperham merged 14 commits into
masterfrom
rails5
Aug 24, 2016
Merged

Enable code reloading in development mode with Rails 5#2457
mperham merged 14 commits into
masterfrom
rails5

Conversation

@mperham

@mperham mperham commented Jul 24, 2015

Copy link
Copy Markdown
Collaborator

Until now Sidekiq has been required to eager load all application code at startup, since Rails reloading has never been thread-safe. This has changed in Rails 5! If the user is running Rails 5 in development, have Sidekiq leverage the new Interlock to safely reload app code.

Testing

gem 'rails', '5.0.0.rc1'
gem 'rack', '2.0.0.rc1'
gem 'sinatra', github: 'sinatra/sinatra'
gem 'sidekiq', github: 'mperham/sidekiq', branch: 'rails5'

Now fire up Sidekiq, edit code and create jobs. You should see code changes immediately reflected in job output.

Comment thread sidekiq.gemspec Outdated

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops.

@davydovanton

Copy link
Copy Markdown
Contributor

Great work 👍
What about status of this PR?

@mperham

mperham commented Jul 26, 2015

Copy link
Copy Markdown
Collaborator Author

Needs testing by people with real rails apps. Not sure if I should merge it or leave it in the branch.

On Jul 25, 2015, at 02:32, Anton Davydov notifications@github.com wrote:

Great work
What about status of this PR?


Reply to this email directly or view it on GitHub.

@mperham

mperham commented Aug 31, 2015

Copy link
Copy Markdown
Collaborator Author

Currently blocked by rails/rails#21006

@mperham

mperham commented Feb 2, 2016

Copy link
Copy Markdown
Collaborator Author

Appears to work with Rails 5.0.0.beta2!

@csxiaodiao

Copy link
Copy Markdown

powerful

@connorshea

Copy link
Copy Markdown

Any updates on this? Will it be merged once Rails 5 is out?

@mperham

mperham commented Apr 13, 2016

Copy link
Copy Markdown
Collaborator Author

Correct, until Rails 5 is released, I won't merge/support the feature.

@houmanka

houmanka commented May 5, 2016

Copy link
Copy Markdown

Hi guys, not sure if I am allowed to post this in here.
When I try to run the sidekiq after updating it I get the following error:
uninitialized constant ActionController::RackDelegation

mattbrictson added a commit to mattbrictson/rails-template that referenced this pull request May 16, 2016
Requires newer versions of Sidekiq and Sinatra, both of which haven't been
released yet.

See: sidekiq/sidekiq#2457
Comment thread lib/sidekiq/cli.rb Outdated
require 'sidekiq/rails'
require File.expand_path("#{options[:require]}/config/environment.rb")

if ::Rails::VERSION::MAJOR > 4 && ::Rails.env.development?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this check if Rails.configuration.cache_classes is set to false instead of relying on a specific environment name?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback!

On Wed, Jun 15, 2016 at 4:15 PM, Edward Rudd notifications@github.com
wrote:

In lib/sidekiq/cli.rb
#2457 (comment):

@@ -231,6 +231,10 @@ def boot_system
end
require 'sidekiq/rails'
require File.expand_path("#{options[:require]}/config/environment.rb")
+

  •      if ::Rails::VERSION::MAJOR > 4 && ::Rails.env.development?
    

Shouldn't this check if Rails.configuration.cache_classes is set to false
instead of relying on a specific environment name?


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/mperham/sidekiq/pull/2457/files/e4d09527c43816706587d86eef3b4036128b465e#r67263057,
or mute the thread
https://github.com/notifications/unsubscribe/AAALXwBfTjj6BiHKfUxGjfJwQiElR9Zeks5qMIedgaJpZM4Ffbrt
.

Comment thread lib/sidekiq/cli.rb
@@ -235,6 +235,10 @@ def boot_system
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this change obviates the above forced eager_load, along with the contortions it requires (for Rails 5.0+, of course).

(Or at least it would, if you still wrapped with the @app.executor when cache_classes is true.)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't have the context for your comment. Could you be more specific?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The block of code just above here (231-235) exists to force eager loading, which (I assume) is because runtime autoloading and threaded workers didn't get along so well.

Autoloading is now threadsafe, as long as the relevant code is wrapped by @app.executor. @app.reloader does that internally, but the condition below is skipping the reloader when cache_classes is true.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, updated, see the commit I named you in.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@Xosmond

Xosmond commented Jul 4, 2016

Copy link
Copy Markdown

So Rails 5 is released

@fusion2004

Copy link
Copy Markdown

And we will be happy when the feature is merged, whenever that may be @mperham. Thanks for all your hard work!

@mperham

mperham commented Jul 5, 2016

Copy link
Copy Markdown
Collaborator Author

Sinatra hasn't released a tag or gem which supports Rack 2.0. I'm reluctant to merge changes which depend on a dependency's master. If you want to run this code, it's easy enough to pull in the branch.

@mperham mperham merged commit be3073a into master Aug 24, 2016
@mperham mperham deleted the rails5 branch August 24, 2016 16:55
@jrochkind

Copy link
Copy Markdown

@matthewd / @thedarkone : Any chance of any documentation or brief overview or pointers to relevant classes for "the new Interlock API"? I'm having trouble understanding what's going on enough to use in my own non-sidekick code that does concurrency such that I've never been able to use dev-mode class-reloading before.

This code looks like it mainly uses Rails.application.reloader.wrap, and one might guess that Rails.application.reloader is an ActionDispatch::Reloader, but the generated docs for that class don't even include the existence of a wrap method, let alone docs for what it does and how it is to be used. The Rails Guide on Autoloading and Reloading Constants also does not seem to have been updated for relevant changes in Rails5.

Any hints available anywhere?

@matthewd

Copy link
Copy Markdown

@jrochkind it's an ActiveSupport::Reloader. The primary PRs are rails/rails#17102 (the interlock API), and rails/rails#23807 (the executor/reloader abstraction).

The relevant API documentation is very vague, partly because that's the point of the abstraction: the API is not offering to do A and B and C for you, but rather to take care of whatever details are necessary to allow your supplied block of code to run safely / with the latest available version of any reloadable code -- and it's a hook mechanism whose actual behaviour will differ depending on what other components/libraries are in play.

While that's a conscious choice for the API, I agree we also need a more detailed discussion of what it actually does, today, when the full framework is loaded -- probably in a guide.

Meanwhile, please feel free to open a "the executor/reloader API is poorly documented" issue on Rails, and then use that to ask any questions you have: that'll both get you the information you need, and help us identify what such a document needs to cover.

@jrochkind

Copy link
Copy Markdown

Thanks @matthewd! With regard to it being intended to be an abstraction, yeah, followed, what's needed is documentation for how one is meant to write code using the new Interlock API such that your code can let it "take care of whatever details are necessary to allow your supplied block of code to run safely", as you say. That's exactly what I want to know.

I don't necessarily need to know what goes on under the hood in current version of Rails -- although an understanding of that is probably a good idea if I'm going to need to debug (which I probably am, either bugs in my own code or in Rails', which happen). But first priority is documentation of the abstraction as abstraction, what is the 'contract', what is it meant to do, how am I meant to use it as an author of code that requires it's protections (like sidekiq).

I'll file an Issue with these sorts of comments, if you think it will be helpful. I'll tag you in the issue if you don't mind, because my experience of filing doc issues on Rails is generally that they simply get closed with a comment to submit better docs if I have it. If I understood it enough to write docs being sure I wasn't misleading anyone, I would, but there's a chicken and egg! (I have some doc commits in the Rails history, I do write docs when I can!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.