Delayed_job Won't Run User defined method

折月煮酒 提交于 2019-12-22 16:41:04

问题


I have been trying to get DelayedJob to run some user defined methods in the background. For this test case I defined the following method in a helper:

 def test_case
    u = User.new
     u.first_name = "JimBob"
     u.last_name = "joe"
     u.email = "itworked@eureka.com"
     u.password = "sailsJ123"
     u.password_confirmation = "sailsJ123"
     u.save
  end

Then, in a controller action, I define:

  def action_name
     #whatever it does outside of this
     test_case

  end

This causes test_case to create a new user when the action here is run. If I try to delay the job, I change it to:

  def action_name
     #whatever it does outside of this
     self.delay.test_case
  end

This causes a delayed_job to be created, but with certain signs that I'm doing this wrong: specifically, the handler in the delayed_job table contains all the information loaded elsewhere in action_name (in this case a very large file of about 50000 characters), not just a simple handler specifying to run test_case or something.

If I change this around to keep testing, I have tried to do:

 def action_name
     #whatever it does outside of this
     u = User.new
     u.first_name = "JimBob"
     u.last_name = "joe"
     u.email = "itworked@eureka.com"
     u.password = "sailsJ123"
     u.password_confirmation = "sailsJ123"
     u.delay.save
  end

This creates a DJ successfully and, as expected, it loads a handler specifying the details (eg u.name => "JimBob"...). But when the job is run no new user gets created. I've even tried to switch it just to destroy a user (i though maybe creating a user with DJ might be hard, given the way password fields are handled) but this doesn't work.

SO long story short:

  1. How can I get DJ to run background methods properly?
  2. How is it that in the cases where delayed jobs are created that look straightforward, no changes are made to the database?

回答1:


This doesn't indicate that something is wrong:

the delayed_job table contains all the information loaded elsewhere in action_name

That would be expected in this case because you're saying this:

self.delay.test_case

and self is the controller that happens to have params and all sorts of other stuff you probably don't care about; DJ will have to serialize self in order to provide the appropriate context for test_case to run. Perhaps you're running into a size limit somewhere with that big file stuck in self.

I think your second "call delay on something else" approach is moving in the right direction.

You could try enquiring a job class:

class ItsAJob
    def perform
        u = User.new
        u.first_name = "JimBob"
        u.last_name = "joe"
        u.email = "itworked@eureka.com"
        u.password = "sailsJ123"
        u.password_confirmation = "sailsJ123"
        u.save
    end
end

# and elsewhere...
Delayed::Job.enqueue(ItsAJob.new)

Or try making your method a class method so you can .delay on a class:

class YourController
    def action_name
        self.class.delay.test_case
    end

    def self.test_case
        u = User.new
        u.first_name = "JimBob"
        u.last_name = "joe"
        u.email = "itworked@eureka.com"
        u.password = "sailsJ123"
        u.password_confirmation = "sailsJ123"
        u.save
    end

end




回答2:


You cannot delay #save on ActiveRecord models since DJ will attempt to reload the model from the database before performing your action. All of the data will be lost. Instead, create a Job class with a #perform method that creates the User.



来源:https://stackoverflow.com/questions/9695440/delayed-job-wont-run-user-defined-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!