delayed_job
delayed_job copied to clipboard
Job failed to load: undefined class/module User::Identity
This is driving me batty, mostly due to the random nature of it.
We are running Rails 4.1 and I have a simple ActiveResource (not ActiveRecord) object called "User" with a method called "update_metadatas" (it takes a json hash as a param). So I'll load up a User object (let's call it u) and then call u.update_metadatas(data). Works great. However, when I do u.delay.update_metadatas(data), things go screwy.
Seemingly depending on the time or day or direction of the wind (ok not really), the above job will immediately fail with:
Job failed to load: undefined class/module User::Identity
The errors aren't that revealing.
Sometimes it will work great with no problems. This behavior happens on both development (local workstation) and production (Heroku).
My guess is that this is a preloading issue . . . i.e., it seems random only because it is affected by when the worker runs (before or after when the rest of the application loads). For example I'll have all the jobs fail for a 2 hour period, and then they'll start working again. I tried the suggestion about turning off config.threadsafe! in production.rb for rake tasks, but that doesn't work for Rails 4.1. I tried the suggestion of adding an initializer like "require 'user'", but that didn't help.
ANY ideas?
P.S. I also run Puma, not sure if that matters (I don't believe Puma is used for the rake tasks though).
The error says it can't find User::Identity
. Which means that is not cleanly autoloading. Look for where that comes from and determine why that wouldn't load.
Yeah, I saw that, no idea where that is coming from. Will continue investigating, wasn't sure if that was more of a generic error.
I'm having the same issue. For some reason delayed jobs isn't autoloading classes properly. Even manually requiring job classes via an initializer isn't fixing this issue for me.
We don't do any loading or autoloading. That is all rails and usually means you have things defined in an unusual way
I'm getting this when I have a job that uses a one of my own modules in the payload. Maybe this is a serialisation problem? or an issue with Rails auto loading
I've been having this issue too, and it is seemingly random. Anyone come up with a solution?
I got this error too, with the undefined class/module being the name of my Custom Job Struct. This issue comes up for me on my staging server, but not on local / development environment. The delayed job is being called within a rake task.
FWIW: ssh'ing in and manually restarting the daemon (a la bin/delayed_job restart
) allowed my job to run without the error.
I'm also randomly getting a similar error (a different class fails to load for me). Sometimes my DJs work, and often they fail with this error. Has anyone come up with a solution?
@DMcKinnon-mdsol, it turns out this whole time I was dealing with this issue, there were multiple instances of the daemon running (due to a faulty deploy script). There are some instructions here for seeing how many instances of delayed_jobs daemon are running and killing them.
Oh, cool. This might actually be my problem, too. Thanks!
I am getting this error, and the suggestion to include a custom initializer that loads the missing class did not work. Also, the suggestion of restarting the delayed_job worker did not work. I don't have multiple delayed_job workers running on the machine either.
Has anyone else figured out another solution? It does not happen every time, only sometimes, but I cannot determine a pattern that makes sense. Here is an example of the failure message:
Job failed to load: undefined class/module NotificationMailer. Handler: "--- !ruby/object:Delayed::PerformableMailer\nobject: !ruby/class 'NotificationMailer'\nmethod_name: :notification\nargs:\n- !ruby/*****\n"
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/backend/base.rb:87:in `rescue in payload_object'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/backend/base.rb:85:in `payload_object'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/backend/base.rb:132:in `max_run_time'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/worker.rb:265:in `max_run_time'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/worker.rb:204:in `block in run'
/usr/local/lib/ruby/2.2.0/benchmark.rb:303:in `realtime'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/worker.rb:203:in `run'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/worker.rb:280:in `block in reserve_and_run_one_job'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:61:in `call'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:61:in `block in initialize'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:66:in `call'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:66:in `execute'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:40:in `run_callbacks'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/worker.rb:280:in `reserve_and_run_one_job'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/worker.rb:187:in `block in work_off'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/worker.rb:186:in `times'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/worker.rb:186:in `work_off'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/worker.rb:150:in `block (4 levels) in start'
/usr/local/lib/ruby/2.2.0/benchmark.rb:303:in `realtime'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/worker.rb:149:in `block (3 levels) in start'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:61:in `call'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:61:in `block in initialize'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:66:in `call'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:66:in `execute'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:40:in `run_callbacks'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/worker.rb:148:in `block (2 levels) in start'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/worker.rb:147:in `loop'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/worker.rb:147:in `block in start'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/plugins/clear_locks.rb:7:in `call'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/plugins/clear_locks.rb:7:in `block (2 levels) in <class:ClearLocks>'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:79:in `call'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:79:in `block (2 levels) in add'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:61:in `call'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:61:in `block in initialize'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:79:in `call'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:79:in `block in add'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:66:in `call'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:66:in `execute'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/lifecycle.rb:40:in `run_callbacks'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/worker.rb:146:in `start'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/command.rb:124:in `run'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/command.rb:112:in `block in run_process'
/usr/local/bundle/gems/daemons-1.2.3/lib/daemons/application.rb:265:in `call'
/usr/local/bundle/gems/daemons-1.2.3/lib/daemons/application.rb:265:in `block in start_proc'
/usr/local/bundle/gems/daemons-1.2.3/lib/daemons/daemonize.rb:84:in `call'
/usr/local/bundle/gems/daemons-1.2.3/lib/daemons/daemonize.rb:84:in `call_as_daemon'
/usr/local/bundle/gems/daemons-1.2.3/lib/daemons/application.rb:269:in `start_proc'
/usr/local/bundle/gems/daemons-1.2.3/lib/daemons/application.rb:295:in `start'
/usr/local/bundle/gems/daemons-1.2.3/lib/daemons/controller.rb:56:in `run'
/usr/local/bundle/gems/daemons-1.2.3/lib/daemons.rb:193:in `block in run_proc'
/usr/local/bundle/gems/daemons-1.2.3/lib/daemons/cmdline.rb:88:in `call'
/usr/local/bundle/gems/daemons-1.2.3/lib/daemons/cmdline.rb:88:in `catch_exceptions'
/usr/local/bundle/gems/daemons-1.2.3/lib/daemons.rb:192:in `run_proc'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/command.rb:110:in `run_process'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/command.rb:91:in `block in daemonize'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/command.rb:89:in `times'
/usr/local/bundle/gems/delayed_job-4.0.6/lib/delayed/command.rb:89:in `daemonize'
/opt/bedboard2admin/bin/delayed_job:5:in `<main>'
I tried creating a file called config/initializers/custom.rb
with the following line:
require 'notification_mailer'
But that did not seem to help. Here is my bin/delayed_job
script for reference:
#!/usr/bin/env ruby
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment'))
require 'delayed/command'
Delayed::Command.new(ARGV).daemonize
And config/environment.rb
, which is referenced by that file:
# Load the Rails application.
require File.expand_path('../application', __FILE__)
# Initialize the Rails application.
AppName::Application.initialize!
And config/application.rb
, which is referenced by that environment.rb
:
require File.expand_path('../boot', __FILE__)
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Bedboard2
class Application < Rails::Application
# some config lines omitted here...
config.autoload_paths << Rails.root.join('lib')
# some config lines omitted here...
end
end
And config/boot.rb
:
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
I'm just confused as to why it works sometimes, and doesn't work other times. The missing file is located in app/mailers/notification_mailer.rb
. Should I explicitly add app/mailers
to the config.autoload_paths
in application.rb
?
Also, here is a sample of my delayed_job.log file from our production server:
I, [2016-11-02T18:43:03.656246 #12782] INFO -- : 2016-11-02T18:43:03+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861072) RUNNING
I, [2016-11-02T18:43:03.948485 #12782] INFO -- : 2016-11-02T18:43:03+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861072) COMPLETED after 0.2921
I, [2016-11-02T18:43:03.953833 #12782] INFO -- : 2016-11-02T18:43:03+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861073) RUNNING
I, [2016-11-02T18:43:04.129653 #12782] INFO -- : 2016-11-02T18:43:04+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861073) COMPLETED after 0.1757
I, [2016-11-02T18:43:04.134292 #12782] INFO -- : 2016-11-02T18:43:04+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861074) RUNNING
I, [2016-11-02T18:43:04.282733 #12782] INFO -- : 2016-11-02T18:43:04+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861074) COMPLETED after 0.1482
I, [2016-11-02T18:43:04.287293 #12782] INFO -- : 2016-11-02T18:43:04+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861075) RUNNING
I, [2016-11-02T18:43:04.455671 #12782] INFO -- : 2016-11-02T18:43:04+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861075) COMPLETED after 0.1682
I, [2016-11-02T18:43:04.460556 #12782] INFO -- : 2016-11-02T18:43:04+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861076) RUNNING
I, [2016-11-02T18:43:04.637698 #12782] INFO -- : 2016-11-02T18:43:04+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861076) COMPLETED after 0.1770
I, [2016-11-02T18:43:04.642223 #12782] INFO -- : 2016-11-02T18:43:04+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861077) RUNNING
I, [2016-11-02T18:43:04.928426 #12782] INFO -- : 2016-11-02T18:43:04+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861077) COMPLETED after 0.2860
I, [2016-11-02T18:43:04.933008 #12782] INFO -- : 2016-11-02T18:43:04+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861078) RUNNING
I, [2016-11-02T18:43:05.142750 #12782] INFO -- : 2016-11-02T18:43:05+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861078) COMPLETED after 0.2095
I, [2016-11-02T18:43:05.149941 #12782] INFO -- : 2016-11-02T18:43:05+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861079) RUNNING
I, [2016-11-02T18:43:05.313470 #12782] INFO -- : 2016-11-02T18:43:05+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861079) COMPLETED after 0.1634
I, [2016-11-02T18:43:05.318028 #12782] INFO -- : 2016-11-02T18:43:05+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861080) RUNNING
I, [2016-11-02T18:43:05.473159 #12782] INFO -- : 2016-11-02T18:43:05+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861080) COMPLETED after 0.1550
I, [2016-11-02T18:43:05.477747 #12782] INFO -- : 2016-11-02T18:43:05+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861081) RUNNING
I, [2016-11-02T18:43:05.651576 #12782] INFO -- : 2016-11-02T18:43:05+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861081) COMPLETED after 0.1737
I, [2016-11-02T18:43:05.656133 #12782] INFO -- : 2016-11-02T18:43:05+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861082) RUNNING
I, [2016-11-02T18:43:05.815682 #12782] INFO -- : 2016-11-02T18:43:05+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861082) COMPLETED after 0.1594
I, [2016-11-02T18:43:05.820303 #12782] INFO -- : 2016-11-02T18:43:05+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861083) RUNNING
I, [2016-11-02T18:43:05.981684 #12782] INFO -- : 2016-11-02T18:43:05+0000: [Worker(delayed_job host:fff2a1b96b42 pid:12782)] Job NotificationMailer.new_case_notification (id=861083) COMPLETED after 0.1612
The worker is clearly working sometimes, but no failures show up in the log. The failures only show up in the delayed_jobs table in the database.
+1 I am getting this as well, seems to be random and I can't duplicate it if I login to the console and make the same call.
We were encountering this error (Rails 5.0.2 and DelayedJob 4.1.2):
Job failed to load: undefined class/module Foo::Bar
We tried require 'foo/bar'
in our initializer/delayed_job.rb
, but that didn't work.
However, require_relative '../../lib/foo/bar'
did work. Seems like delayed jobs might be doing some weird autoloading on it's workers.
I'm not sure if it's helpful to anyone besides me, I use rake to start my delayed_job workers, and I just learned that rails overrides eager_load
to be false
for all rake commands. This was causing issues with undefined class names for me
So I just ran into this issue and I can confirmed that after reading this the only think i needed to do was adding the require 'foo_bar'
on my initializer/delayed_job.rb
and it worked
I was having uninitialized class errors and the issue was due to my worker pools running off of an older release. See issue #911.
In
config/initializers/application.rb
add at the end the following line
load(relative/path/to/your/rubyfile)
in my case I needed delay one method from Device.rb
that I placed in lib
folder...
I looked deeper into my stack trace and noticed that psych was doing some class loading. I then read this SO about it having issues resolving serialized classes: https://stackoverflow.com/questions/4705867/rails-doesnt-load-classes-on-deserializing-yaml-marshal-objects
I added this monkey patch (for Rails4) and haven't had any problems since:
module Psych::Visitors
ToRuby.class_eval do
alias :resolve_class_without_autoload :resolve_class
def resolve_class klassname
begin
require_dependency klassname.underscore
rescue NameError, LoadError
end
resolve_class_without_autoload klassname
end
end
end
I think I'm also being affected by the same issue, here's the error message I'm getting:
Job failed to load: undefined class/module ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer
As with the other above, it's intermittent and I can't see what's causing it.
App is on Heroku, using DJ to send emails with a worker. Because it's an ActiveRecord class/module that isn't being found, would that still be an autoloading issue in Rails?
Is the monkey patch above preventing the error from bubbling up from Psych?
@maxshelley did you recently do a rails upgrade? That looks more like an ActiveRecord internal that may have moved between versions.
@albus522 Yes, we have, but that errors seem to occurring for jobs that were, I think, created after the update. I don't feel like I've brought enough information to this conversation, I'm going to dig further, thank you for taking the time to respond and I think you're right about the Rails update being part of my issue.
I made a pull request to help with this problem. Meanwhile you can use this lines
# config/initializers/delayed_job.rb
# Monkey patch to use old class references
module Psych
class << self; attr_accessor :old_class_references end
@old_class_references = {}
class ClassLoader
private
def find klassname
klassname = ::Psych.old_class_references[klassname] || klassname
@cache[klassname] ||= resolve(klassname)
end
end
module Visitors
class ToRuby < Psych::Visitors::Visitor
def revive klass, node
if klass.is_a? String
klassname = ::Psych.old_class_references[klass] || klass
klass = Kernel.const_get(klassname) rescue klassname
end
s = register(node, klass.allocate)
init_with(s, revive_hash({}, node), node)
end
end
end
end
# Add all old dependencies (hash keys) pointing to new references (hash values)
Psych.old_class_references = {
'ActiveRecord::AttributeSet' => 'ActiveModel::AttributeSet'
# ...
}
Just quickly contributing our situation here.
In one of our views, we were trying to load the handler
via YAML.load( job.handler )
and got the following error:
ActionView::Template::Error (undefined class/module Facility):
For some reason, it could not load the Facility
model properly, even though this is in our Rails app where the Facility
model has already been loaded (and used).
The quick fix we used was literally calling the Facility
model prior to calling YAML.load( job.handler )
, like this:
<% Facility -%>
<%= YAML.load( job.handler ).object.name %>
Not sure what the root issue is but maybe that will help somebody in the meantime.
Cheers.
@DMcKinnon-mdsol, it turns out this whole time I was dealing with this issue, there were multiple instances of the daemon running (due to a faulty deploy script). There are some instructions here for seeing how many instances of delayed_jobs daemon are running and killing them.
Thanks! This helps me to solve my issue! :+1: