问题
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:
- How can I get DJ to run background methods properly?
- 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