New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rails' eager load hooks at not invoked #1791
Comments
How's that look? |
@jonleighton Can you double check and close this issue if it looks correct? |
Cheers, will test it against our app |
Ok, setting Rails::Application.initializer "sidekiq.eager_load" do
Rails.application.config.eager_load = true
end The block gets run after |
Ok, try master again. |
Yep, that works |
I just updated an app to Sidekiq 3.2.0, and starting seeing |
A couple additional info: the uninitialized constant mentioned above is an ActiveRecord model under app/models inside a Rails engine. |
Cc @jonleighton
|
@fabiokr are you seeing the issue inside the Sidekiq process? do you have a standard |
@jonleighton Btw, this is Rails 3.2.19. Yes, it happens under the Sidekiq process. For the specific environment files, we share some of the configurations within the engine like this: # the_app/config/environments/development.rb
require 'the_engine/engine/config/development'
TheApp::Application.configure do
end
# the_engine/engine/config/development.rb
Rails.application.class.configure do
config.cache_classes = false
config.whiny_nils = true
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.action_mailer.raise_delivery_errors = false
config.active_support.deprecation = :log
config.action_dispatch.best_standards_support = :builtin
config.active_record.auto_explain_threshold_in_seconds = 0.5
config.assets.compress = false
config.assets.debug = true
end Also, it fails in the first time a job is run and on subsequent runs as well. |
Right, I've realised that the solution I suggested is only compatible with Rails 4+, since
|
👍 for extra hacks. We're still on Rails 3.2 at the moment. Somehow we still have dependencies that aren't ready for Rails 4 and we haven't had time to hack on them or find replacements. /cc @morganick |
I can't really drop 3.2 without a major version bump. When does 3.2 go EOL?
|
Looks like Rails 3.2 is in "severe security fixes only" mode but Sidekiq 3 shouldn't change supported versions. We need a Sidekiq 3.2.1 release which works on Rails 3.2, so reverting is probably the right thing to do here. I'm happy to have a 4-x branch with these changes which is Rails 4.0+ only. We'll make that branch master after a month or so to let 3.2.x settle. Anyone want to do that? |
And keep around a branch for rails 3.2 which will be bug/security fix only? |
Yes, once master becomes 4.x only, we'd create a 3-x branch and find a volunteer to maintain the branch. |
That plan sounds fine to me. Sorry about the breakage. |
Support v3 and v4 eager load logic, #1791
This patch seems to have caused a double-loading issue, at least in Ruby 2.1.1. Requiring |
@stouset Please prove it with a simple app which reproduces the problem. |
I say prove it because 5 minutes of me trying couldn't reproduce any constant redefinition warnings. |
I investigated further; not sure if this should be considered a bug in sidekiq or Rails, or if it's working as intended. The problem is when a file in an eager loaded directory (e.g., It's probably not a bug in sidekiq, but it does seem to be exposed by the eager loading hoops being jumped through here. I can provide a POC, but wanted to get your thoughts on if it's something you think sidekiq is responsible for first. |
General rule of thumb: if your application code is using |
It's not the application code. The application code is using |
Why is your application requiring it if Rails will eager load it for you anyways? |
Try switching the require to require_dependency On 17/09/14 05:31, Mike Perham wrote:
|
As I said earlier,
Rails' eager loading will load the file, as it preemptively calls
All Again, I'm unsure whether or not this is a bug in Rails, a bug in sidekiq, or "works as intended". At the very least, the behavior only seems to be triggered by sidekiq due to the hoops it jumps through to ensure Rails' classes are eager loaded. |
Thanks for your patience and explanation. This is a tricky situation. What about moving the file out of the eager load path and doing a require as normal in your initializer? |
Yes, I did that as a workaround (moved to |
Right, interesting. I think I'd consider it a bug a Rails to be honest, On 17/09/14 19:26, Stephen Touset wrote:
|
+1 for resolving this issue for Rails 3. I'm seeing the same issue - installed Sidekiq, ran bundle exec sidekiq, got double-loading errors from classes that need to be force-loaded in dev mode to allow for some meta-programming. As this method works for dev, test & production use in Rails, it seems that the issue should be handled on the Sidekiq side of things. What is the purpose behind eager-loading after the environment require? |
Using Rails 4.2.0 we still encountered this issue when explicitly requiring a file that also fell into the eager_load path. Our solution was to add ActiveSupport::Dependencies.mechanism = :require to our |
We are also getting a double-loading issue. Tons of warnings about constants being reinitialized. We have a requirement to use We now have a requirement to |
We experienced a different issue caused by Sidekiq's hacky Rails loading. We set up a Rails.application.configure do
config.active_job.queue_adapter = :sidekiq
end This initializer worked great for our web server and other processes. They enqueue jobs to Sidekiq fine. But we discovered that within the Sidekiq worker process only the initializer was running but not taking effect. Within a Consequently, when a job tried to enqueue other jobs, they actually ran inline. What fixed it for us was moving the code above to the
I believe calling |
I was also having issues with the way Sidekiq boots rails 4. I ended up making the following change to my development.rb. config.cache_classes = !!Sidekiq.server?
config.eager_load = !!Sidekiq.server? This had the benefit of running sidekiq in It seems the existing sidekiq initializer runs too late for some of the boot code in our rails app. |
Had a custom directory inside
Doing exactly what @ryansch resolved it. |
I am late here. But can I ask why does https://github.com/mperham/sidekiq/blob/master/lib/sidekiq/cli.rb#L236 |
eager loading is required in Rails 4 because Sidekiq is multithreaded. |
IMHO, Sidekiq should allow Rails environment decide whether to eager load or not. For example, on Please, note also that multithreaded problem in the context of loading of constants is not solved with the eager loading at Sidekiq (nor at Rails) level anyway. There still might be constants that are needed by Sidekiq, but Rails developer might not have put them inside the eager loaded paths. In summary, I do not find a reason to make
|
@pmatsinopoulos I have no interest in changing the behavior for Rails 3 and 4. You might be interested in this pull request #2457 |
Sidekiq triggers eager loading by calling
Rails.application.eager_load!
. This causes all the files inconfig.eager_load_paths
to be loaded, but it doesn't allow thebefore_eager_load
hook to run, nor does it result in theeager_load!
methods of theconfig.eager_load_namespaces
being called.To do that, we need
config.eager_load
to be set.Rather than loading
config/environment.rb
only, Sidekiq could loadconfig/application.rb
, setRails.application.config.eager_load = true
, and then loadconfig/environment.rb
. I believe this would have the desired effect. We do something similar in spring.In the meantime, here's a workaround I'm using:
Cheers
The text was updated successfully, but these errors were encountered: