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

NoMethodError with delayed_job #323

Closed
tshr opened this issue Dec 22, 2011 · 28 comments
Closed

NoMethodError with delayed_job #323

tshr opened this issue Dec 22, 2011 · 28 comments

Comments

@tshr
Copy link

tshr commented Dec 22, 2011

I am trying to implement delayed_job for a mailer on a rails 3.1.0 app locally with ruby 1.8.7 .

Following the documentation I am making the delay call from my controller as follows:

EventMailer.delay.event_message_email(current_user, @event_message)

This causes the task to be added to the job table but when I run rake jobs:work it logs the following error:

Class#event_message_email failed with NoMethodError: undefined method `event_message_email' for Class:Class - 6 failed attempts

Calling the mailer method without delay works fine, and I am running it on the default rails server so its not the issue with Thin mentioned in the FAQ. Any idea whats wrong? Thanks.

@danielmorrison
Copy link
Member

Have you restared the job runner? It could be something as simple as that.

Otherwise, check that it is saving EventMailer in the jobs table.

-Daniel

Daniel Morrison
[i] Collective Idea
http://collectiveidea.com
http://ideafoundry.info
25 West 8th Street, Suite 200
Holland, MI 49423
616-990-0155
daniel@collectiveidea.com

On Dec 22, 2011, at 11:14 AM, tshr wrote:

I am trying to implement delayed_job for a mailer on a rails 3.1.0 app locally with ruby 1.8.7 .

Following the documentation I am making the delay call from my controller as follows:

EventMailer.delay.event_message_email(current_user, @event_message)

This causes the task to be added to the job table but when I run rake jobs:work it logs the following error:

Class#event_message_email failed with NoMethodError: undefined method `event_message_email' for Class:Class - 6 failed attempts

Calling the mailer method without delay works fine, and I am running it on the default rails server so its not the issue with Thin mentioned in the FAQ. Any idea whats wrong? Thanks.


Reply to this email directly or view it on GitHub:
#323

@tshr
Copy link
Author

tshr commented Dec 22, 2011

Thanks for replying. Assuming you mean exiting and then rerunning the task rake jobs:work then, yes. Also I did check the jobs table and the jobs are being saved there, and the tasks are retried regularly as expected but just always fail.

@bryckbost
Copy link

Which version of delayed_job is this? 2.X or one of the prerelease 3.0s?

@tshr
Copy link
Author

tshr commented Dec 24, 2011

Ah its one of the preleases: 3.0.0.pre4, is there a better one to use?

@clayheaton
Copy link

I'm having this same issue running on heroku cedar stack with delayed_job (3.0.0.pre4). I run the same version in my dev environment, however, and it works without a problem.

More info:

I'm calling this in my User model:

def mail_confirmation
  UserMailer.registration_confirmation(self).deliver
end

UserMailer looks like this:

class UserMailer < ActionMailer::Base
  default from: "admin@mysite.com"

  def registration_confirmation(user)
    @user = user
    mail(
          :to => "#{user.full_name} <#{user.email}>", 
          :subject => "Registered at My Site"
        )
  end

end

I get this error on heroku:

Class#registration_confirmation failed with NoMethodError: undefined method `registration_confirmation' for Class:Class - 2 failed attempts

@clayheaton
Copy link

Looks like the same as issue 306

@tshr
Copy link
Author

tshr commented Dec 27, 2011

Hi, I asked this question on stackoverflow and there was a useful reply:

http://stackoverflow.com/questions/8602203/nomethoderror-with-delayed-job-collectiveidea-gem

He said that the !ruby/object:Delayed::PerformableMailer in the handler field should be recorded as !ruby/struct:Delayed::PerformableMailer. I tried changing this directly in my dev database for a queued job and when I ran rake jobs:work it did remove it from the table (it did not say the task was executed in the shell, but perhaps that i as expected). The responder recommends downgrading to 2.1.2, but I am concerned this will not work with Rails 3 mailers. Can you suggest any other solution?

@tshr
Copy link
Author

tshr commented Dec 29, 2011

I went ahead and switched to using 2.1.2 and this resolved the issue both on dev and production

@lstone
Copy link

lstone commented Jan 8, 2012

I also have the exact same issue.

@asanghi
Copy link

asanghi commented Jan 8, 2012

same issue. Using Rails 3.0.10 with ruby1.8.7

@asanghi
Copy link

asanghi commented Jan 8, 2012

On the console

YAML.load MyActiveRecordModel.to_yaml
=> Class
YAML.parser.class.name
=> "YAML::Syck::Parser"

I'm running on ruby1.8.7, Rails 3.0.10, gem 1.8.11, bundler version 1.0.21
Tried with same result on Ubuntu/OSX
Tried with development mode and production mode with similar results

MyActiveRecordModel.to_yaml
=> "--- !ruby/class MyActiveRecordModel\n"

@pld
Copy link

pld commented Jan 9, 2012

Same issue using Rails 3.1.0, Ruby 1.8.7, gem 1.8.15, bundler 1.0.21.

The database shows the wrong class:

`````` !ruby/object:Delayed::PerformableMailer```

When called on the submit method, this fails with the error
Class#submit failed with NoMethodError: undefined method `submit' for Class:Class

I can also confirm that downgrading to 2.1.2 resolves the issue. With the database entry now correct:
!ruby/struct:Delayed::PerformableMailer

@markaharper
Copy link

Same issue using rails 3.1.0, ruby-1.9.2, gem "delayed_job_active_record" (delayed_job 3.0).

Downgraded to 2.1.4 resolved the issue.

Please Note: 2.1.2 and 2.1.3 have issues when I've run them using ruby-1.9.2 as follows:

delayed_job-2.1.3/lib/delayed/yaml_ext.rb:30:in remove_method: method to_yaml not defined in Class (NameError)

https://github.com/benhoskings/delayed_job/commit/c3a28f9714568c887271e492dd8c6710965278e8#diff-0

@bryckbost
Copy link

With the latest comments, it seems serialization is the issue and the overrides aren't catching the performable mailers.

@asanghi
Copy link

asanghi commented Jan 10, 2012

@bryckbost yes the problem is with serialization but it's not limited to performable mailers. I'm seeing the problem when using delay as a class method on any class.

@bryckbost
Copy link

There's a fix in 0234444. If possible, can I get some verification this fixes the issue?

@turadg
Copy link

turadg commented Jan 15, 2012

@bryckbost yes, it's fixed. I had the same problem (Ruby 1.9.3, Rails 3.2rc2, Heroku Cedar) and after switching from the released gem to the current git master, it went went away.

Note to others, the handler inserted is still --- !ruby/object:Delayed::PerformableMailer.

@HagerAli
Copy link

I have faced same problem I was

ruby 1.9.2-p290 , rails 3.0.3 , and delayed_job 2.1.2 , daemons 1.1.5

downgrading ruby version to 1.9.2-p0 solved the problem.

@kylejginavan
Copy link

I' have this the following:

rbenv local 1.9.2-p290
gem "rails", "3.2.1"
gem "daemons", "1.1.8"
TRIED BOTH
gem "delayed_job", :git => "https://github.com/collectiveidea/delayed_job.git", :ref => "cd89cbb55886af597028e2618f16131200aad4b9"
AND
gem "delayed_job", "3.0.1"
gem "delayed_job_active_record", "0.3.2"

However, I still receive Delayed::PerformableMailer... error described here.

@mathias
Copy link

mathias commented Mar 22, 2012

This is still an issue with the released version as well as Github master HEAD revision.

Please reopen.

@bryckbost
Copy link

@mathias Shoot, sorry to hear it's still an issue for you. Can you let me know which version of Ruby you're on, the backend you're using and if Rails, which version?

Thanks.

@kylejginavan
Copy link

@bryckbost I have that info in my comment. PSQL is my backend.

@mathias
Copy link

mathias commented Mar 23, 2012

Pulling versions out of the .rvmrc and Gemfile here:

ruby-1.9.3-p125,

delayed_job_active_record (0.3.2)
activerecord (> 2.1.0)
delayed_job (3.0.1)

rails (3.2.1)
actionmailer (= 3.2.1)

Server environment is Heroku Cedar with PostgreSQL, but we weren't getting Mailers to send mail locally in our tests, so we haven't been able to get this out to the server yet.

@bryckbost
Copy link

@mathias And you're experiencing NoMethodErrors with your mailers in your tests?

@oelmekki
Copy link

Hello,

I had the same issue locally, using :

gem 'delayed_job', '3.0.1'
gem 'delayed_job_mongoid', '1.0.8'

The problem was that we use syck as yaml engine (and we can't change for psych). In [Delayed::Job::Base#payload_object](gem 'delayed_job', '3.0.1' # to use workers on heroku
gem 'delayed_job_mongoid', '1.0.8' # to use delayed jobs with mongoid), when the instance is deserialized, syck will create a Class instance in @object instead of the original class (which was an UserMailer, in our case).

Since This method is only called in a worker, when handling jobs, I monkey patched it to change yaml engine on the fly. I also had to patch PerformableMailer#perform, because it was sending "String 'UserMailer' has no method <our mailer method>" errors.

Here is my patch.

It works well locally and fix the errors.

But sending mails on heroku (on cedar stack) will simply fail without any error. Delayed job logs show the job has been processed, with "0 fail", but don't show the "sending mail to" log line as expected, and doesn't send mail. I suspect it has something to do with exceptional rescuing the exception or something.

At this point, I can't affirm the heroku app problem is a delayed_job one. I'll keep you posted, my next move will be to downgrade delayed_job and delayed_job_mongoid and see if it helps.

@oelmekki
Copy link

Ok, downgrading didn't help, same issue occured.

I tried that, in a heroku rails console :

irb(main):001:0> class Foo; def self.bar; throw Exception.new('hello'); end; end
=> nil

irb(main):002:0> Foo.delay.bar
=> #<Delayed::Backend::Mongoid::Job _id: 4f6dd37ad8cbd00004000004, _type: nil, created_at: 2012-03-24 14:00:26 UTC, updated_at: 2012-03-24 14:00:26 UTC, priority: 0, attempts: 0, handler: "--- !ruby/object:Delayed::PerformableMethod \nargs: []\n\nmethod_name: :bar\nobject: !ruby/class Foo\n", run_at: 2012-03-24 14:00:26 UTC, locked_at: nil, locked_by: nil, failed_at: nil, last_error: nil, queue: nil>

and got, in rake jobs:work output :

[Worker(host:<host> pid:4)] 1 jobs processed at 15.0934 j/s, 0 failed ...

It should have failed on object deserialization anyway, since Foo doesn't exist in the memory context the worker is launched in, but, heh, I would have loved to have any error.

It's worth mentionning that we were previously on a bamboo stack, with the same code and delayed_job gems versions, and everything ran just fine.

I've requested an exceptional's interface access to my CTO. More on this later.

@jasonij
Copy link

jasonij commented Dec 19, 2012

@oelmekki thank you for your solution, it fixed the Delayed Job NoMethodError problem for me!

I then had to require some models which were present when I ran payload_object.perform locally or from Heroku console but were missing when my Heroku worker called jobs:work on its own, producing this error:

"Delayed::DeserializationError: Job failed to load: undefined class/module ModelMyMailerNeeded"

Just mentioning this in case anyone else has this problem and downgrading does not work. Just remember to load whatever models and libs your mailers need.

@paveltyk
Copy link

paveltyk commented Nov 6, 2013

Had the same YAML serialization problem on Heroku Cedar stack, Ruby 1.9.2, Rails 3.1.12, DJAR 4.0.0. It seems like web server was using different serializer than DJ. Changing Procfile helped to solve the problem: web: bundle exec thin start -R config.ru -e $RACK_ENV -p $PORT to web: bundle exec rails server thin -p $PORT -e $RACK_ENV

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