delayed_job doesn't work with Rails ActiveRecord scope
-
02-06-2021 - |
题
I have delayed_job 3.0.2 installed, and it works with method calls on objects. However, if I call a scope on a class, for example,
Listing.delay.all
then I get error stack level too deep
. This happens if I call any scope on any class I have.
Is this error by design? What's the reason I get stack level too deep
error here?
Thank you.
解决方案
Using delayed_job properly
To answer your question indirectly, it looks like you're not using delayed_job right. I'll explain what your code does and suggest what you probably are trying to do.
Listing.delay.all
The method following delay
(in this case, all
) will get executed in the background. Instead of returning an Array of Listings, it will return a Delayed::Backend::ActiveRecord::Job object. This isn't what is happening in your case, but I'll get to that.
Any job that you background should have a side effect, since the return value of the delayed jobs are not stored. Usually, the side effect is to store something in a database, create a file, or something else that can be detected and used later. By looking at the delayed_job jobs table, you can see that the return value is not stored.
> Delayed::Backend::ActiveRecord::Job.column_names
=> ["id", "priority", "attempts", "handler", "last_error", "run_at", "locked_at", "failed_at", "locked_by", "queue", "created_at", "updated_at"]
That said, the Listing.all
and all the other scope methods do not have any side effects; they only looks up the scoped Listings and return them. When using delayed_job, be sure to use it only on methods that have side effects, such as updating the database, etc.
Unfortunately, without knowing what you're trying to accomplish, it's hard to give advice on how to use delayed_job in your scenario, or even if it's the right tool for the job.
Your error message - stack level too deep
First, I'll say that getting a stack level too deep error on Listing.delay.all
is not normal. I was able to use it on an ActiveRecord model User
in my Rails 3 app with delayed_job 3.0.2, and it worked fine. (It didn't do anything worthwhile, but it returned a Job instead of throwing the error you got.)
> User.delay.all
=> #<Delayed::Backend::ActiveRecord::Job id: 1, priority: 0, attempts: 0, handler: "--- !ruby/object:Delayed::PerformableMethod\nobject:...", last_error: nil, run_at: "2012-05-02 02:10:39", locked_at: nil, failed_at: nil, locked_by: nil, queue: nil, created_at: "2012-05-02 02:10:39", updated_at: "2012-05-02 02:10:39">
Again, there's not much anyone can do to help you figure out that error without more information. I recommend starting with figuring out if delayed_job is really the right tool for what you're doing (it's not if you're using it to get data to pass to a view), use it properly, and then see if you're still having the issue.
其他提示
You should create a custom job and then enqueue it.
class UserJob < Struct.new
def perform
User.all
end
end
Delayed::Job.enqueue UserJob.new()