Skip to content
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

Delayed::Job no longer defined in initializers #185

Closed
severin opened this issue Dec 11, 2020 · 16 comments
Closed

Delayed::Job no longer defined in initializers #185

severin opened this issue Dec 11, 2020 · 16 comments

Comments

@severin
Copy link

severin commented Dec 11, 2020

We have some initializers in our app that do schedule recurring jobs if they are not scheduled yet (using the delayed_job_cron gem under the hood), so basically code like this:

# config/initializers/recurring_jobs.rb

if Delayed::Job.where('handler LIKE "%SomeRecurringJob%"').blank?
  Delayed::Job.enqueue(SomeRecurringJob.new, cron: '* * * * *')
end

Since 4.1.5 this results in NameError: uninitialized constant Delayed::Job. Looking at the changes it is very probably due to #172 which changed the requireing of the relevant code to only happen after initialization.

@severin
Copy link
Author

severin commented Dec 11, 2020

I can work around the issue by adding

require 'delayed/backend/active_record'
Delayed::Worker.backend = :active_record

at the beginning of the initializers, but that does not feel right.

@orien
Copy link
Contributor

orien commented Dec 11, 2020

I have a similar problem. I'm configuring the reserve_sql_strategy option as detailed in the readme:

Delayed::Backend::ActiveRecord.configuration.reserve_sql_strategy = :default_sql

This has been working till version 4.1.5 where it produces an error:

/my-rails-app/config/initializers/delayed_job.rb:3:in `<top (required)>': undefined method `configuration' for Delayed::Backend::ActiveRecord:Module (NoMethodError)

Adding the require also resolves it.

This does seem related to the change in #172.

@ansonhoyt
Copy link

ansonhoyt commented Dec 11, 2020

My initializers broke with uninitialized constant Delayed::Job too.

I've never used one, but I think we could move our initializer to be an after_initialize block. Just have to make sure it is defined after the Delayed Job railtie defines its after_initialize block. Looking at https://guides.rubyonrails.org/configuring.html#initialization-events, I don't see when my configs are run, so I'm not sure if an after_initialize added to my config file would run after theirs (they execute in order). Maybe I can simply define the after_initialize in my current initializer. Initializers are clearly run after gems are loaded and their railties are run.

@ansonhoyt
Copy link

Yep, this seems to work for me:

# config/initializers/delayed_job_extensions.rb
module DelayedJobExtensions
  # my customizations
end

- Delayed::Job.prepend DelayedJobExtensions
+ Rails.application.configure do
+   config.after_initialize do
+     Delayed::Job.prepend DelayedJobExtensions
+   end
+ end

No errors and my customizations are available in the console. I think you could do something similar.

@ansonhoyt
Copy link

I would be nervous simply adding a require to your initializer. Looking at #172, you'll possibly reintroduce that issue to your app.

@albus522
Copy link
Member

I forgot that change hadn't been released. I need to circle back and update the changelog and probably add more documentation.

If you can, wrap what you need to run in an after_initialize like @ansonhoyt suggests, that will be the safest bet and your block will run after DJ's because DJ's is setup when the Bundler.require(*Rails.groups) runs in application.rb.

If you can't use after_initialize,

require 'delayed/backend/active_record'
Delayed::Worker.backend = :active_record

will work, however make sure your initializer runs after any other ActiveRecord configuration initializers. The app initializers are usually run in alphabetical order by filename, so this can usually be accomplished by prefixing your initializer filename with z's like zzzzz_my_late_run_intializer.rb. There are a number of ActiveRecord configuration items that won't apply after ActiveRecord loading triggers and the rails team refuses to consider that a bug.

@jdelStrother
Copy link

make sure your initializer runs after any other ActiveRecord configuration initializers. The app initializers are usually run in alphabetical order by filename, so this can usually be accomplished by prefixing your initializer filename with z's like zzzzz_my_late_run_intializer.rb. There are a number of ActiveRecord configuration items that won't apply after ActiveRecord loading triggers and the rails team refuses to consider that a bug.

Wouldn't something like this be a better way of accomplishing that?

ActiveSupport.on_load(:active_record) do
  require "delayed/backend/active_record"
  Delayed::Worker.backend = :active_record
end

@albus522
Copy link
Member

ActiveSupport.on_load(:active_record) won't work reliably because that relies on something triggering ActiveRecord to load. If nothing triggers the load, DJ never gets setup.

@jdelStrother
Copy link

Ugh - yeah, ok. Can't see it happening in production due to eager loads, but I guess it might cause problems in development.

@thoughtafter
Copy link

I ran into this. This is a breaking change in a patch update. I'm not sure if the version numbers are locked to delayed_job but I definitely did not expect this update to break my app. I haven't fully grokked #172 so maybe this is a good path forward but probably some warning and documentation about breaking changes and the pros/cons of different fixes might be warranted.

@philayres
Copy link

I think this may have caused the following in my app when I upgraded from 4.1.4 to 4.1.5 last night: undefined method `where' for Delayed::Job:Class (NoMethodError) Did you mean? when. I'm adding this in case anybody else tries to search the error.

The error occurs in an initializer, so I added the block as suggested:

Rails.application.configure do
  config.after_initialize do
    # original code
  end
end

This seems to work (at least Rails will start now).

@philayres
Copy link

This also broke for me in another way (but only in the production environment). I had a small utility class that inherited from Delayed::Job like this:

class JobReview < Delayed::Job
    # implementation
end

In development it loads fine, but in production this causes the unitialized constant issue. Obviously wrapping this the same as above for initializers doesn't make sense. I use this rarely, so for now I have just removed the class, but others may come across this if inheriting Delayed::Job for some reason.

@skipchris
Copy link

Seconding/thirding the comments above. This may well be the ‘right’ change, I haven’t had a chance to properly digest the issue, but making a breaking change in a minor version bump is a bit much!

JanZerebecki added a commit to JanZerebecki/crowbar-core that referenced this issue Jan 21, 2021
There was a breaking change in version 4.1.5 of the gen
delayed_job_active_record:
collectiveidea/delayed_job_active_record#185

Resulting failure:
$ bin/rake db:create db:migrate
[...]
NameError: undefined method `reserve' for class `Class'
/home/travis/build/crowbar/crowbar-core/crowbar_framework/config/initializers/delayed_job_log_silencer.rb:22:in `alias_method'
[...]
JanZerebecki added a commit to JanZerebecki/crowbar-core that referenced this issue Jan 21, 2021
There was a breaking change in version 4.1.5 of the gem
delayed_job_active_record:
collectiveidea/delayed_job_active_record#185

Resulting failure:
$ bin/rake db:create db:migrate
[...]
NameError: undefined method `reserve' for class `Class'
/home/travis/build/crowbar/crowbar-core/crowbar_framework/config/initializers/delayed_job_log_silencer.rb:22:in `alias_method'
[...]
JanZerebecki added a commit to skazi0/crowbar-core that referenced this issue Jan 22, 2021
There was a breaking change in version 4.1.5 of the gem
delayed_job_active_record:
collectiveidea/delayed_job_active_record#185

Resulting failure:
$ bin/rake db:create db:migrate
[...]
NameError: undefined method `reserve' for class `Class'
/home/travis/build/crowbar/crowbar-core/crowbar_framework/config/initializers/delayed_job_log_silencer.rb:22:in `alias_method'
[...]
skazi0 pushed a commit to skazi0/crowbar-core that referenced this issue Jan 22, 2021
There was a breaking change in version 4.1.5 of the gem
delayed_job_active_record:
collectiveidea/delayed_job_active_record#185

Resulting failure:
$ bin/rake db:create db:migrate
[...]
NameError: undefined method `reserve' for class `Class'
/home/travis/build/crowbar/crowbar-core/crowbar_framework/config/initializers/
delayed_job_log_silencer.rb:22:in `alias_method'
[...]
JanZerebecki added a commit to JanZerebecki/crowbar-core that referenced this issue Jan 25, 2021
There was a breaking change in version 4.1.5 of the gem
delayed_job_active_record:
collectiveidea/delayed_job_active_record#185

Resulting failure:
$ bin/rake db:create db:migrate
[...]
NameError: undefined method `reserve' for class `Class'
/home/travis/build/crowbar/crowbar-core/crowbar_framework/config/initializers/
delayed_job_log_silencer.rb:22:in `alias_method'
[...]

(cherry picked from commit cb42206)
@jacobjlevine
Copy link

Don't know if this will be helpful for all of you, but I had an initializer that broke with this update and I was able to find a relatively straightforward resolution as detailed in this issue: #188.

@seandilda
Copy link

I'm also seeing this, but with the error:

NameError: uninitialized constant Delayed::DelayProxy::Job

This happens if you try to use #delay method to delay a method call. I'm adding it to the thread for anyone else searching for the error.

@albus522
Copy link
Member

Ok. I was hoping to come up with a better solution, but didn't, and time got away from me. I have pushed out 4.1.6 which only rolls back the loading change. Using after_initialize should not break with the update, but it will no longer be needed.

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

No branches or pull requests

10 participants