我有一个Rails 5应用程序,它利用延迟作业从外部API提取数据并将其保存在数据库存储中,
但是,当我从API发出要进行播种的请求时,它在同一个种子请求中排队两次,而不是处理一次。
初步观察,我确实看到两条记录的处理程序与另一条记录完全不同。下面发布的是我尝试过的代码片段。
需要了解为什么会发生这种情况。寻求任何帮助将不胜感激。预先感谢。
控制器代码
class MovieController < ApplicationController
def new_movie_seed_request
@languages = Language.all.by_lang_name
@movie = Movie.new
end
def seed_request_for_movie
@movie_title = params["mov_title"]
@movie_language = params["mov_language"]
if params.present? && params["mov_title"].present? && params["mov_language"].present?
Delayed::Job.enqueue SeedMovieViaTmdbJob.new(params["mov_title"], params["mov_language"])
flash.now[:success] = 'Request for seeding has been submitted successfully'
else
flash[:danger] = 'Please enter valid movie title and movie language in order to proceed with the seeding request'
redirect_to action: "new_movie_seed_request"
end
end
end
将请求排队后的延迟的工作表记录。
INSERT INTO "delayed_jobs" ("handler", "run_at", "queue", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["handler", "--- !ruby/object:ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper\njob_data:\n job_class: SeedMovieViaTmdbJob\n job_id: b21ae8e7-65ec-4960-b697-d6f056c275da\n provider_job_id: \n queue_name: default\n priority: 0\n arguments:\n - Gully Boy\n - hi\n executions: 0\n locale: en\n"], ["run_at", "2019-03-22 09:20:41.852410"], ["queue", "default"], ["created_at", "2019-03-22 09:20:41.852566"], ["updated_at", "2019-03-22 09:20:41.852566"]]
INSERT INTO "delayed_jobs" ("handler", "run_at", "queue", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["handler", "--- !ruby/object:SeedMovieViaTmdbJob\narguments:\n- Gully Boy\n- hi\njob_id: b21ae8e7-65ec-4960-b697-d6f056c275da\nqueue_name: default\npriority: \nexecutions: 0\n"], ["run_at", "2019-03-22 09:20:41.877060"], ["queue", "default"], ["created_at", "2019-03-22 09:20:41.877122"], ["updated_at", "2019-03-22 09:20:41.877122"]]
请注意已创建的两个记录的处理程序属性中的更改。
答案 0 :(得分:0)
啊哈!
挂钩:https://github.com/collectiveidea/delayed_job#hooks
Delayed :: Job有一个入队钩子,当入队时,该钩子在Job类上调用enqueue
方法。如果您的工作恰好是ActiveJob,这将触发ActiveJob :: Base类定义的入队方法,该方法实际上再次将工作排队! (这次是主动工作)
解决方案:如果要通过调用Delayed :: Job.enqueue创建要排队的自定义作业,请不要从ActiveJob继承!只需使用带有perform
方法的普通旧Ruby对象即可。 (或者,您可以使用不执行任何操作的方法来覆盖enqueue
方法,但实际上根本不需要从ActiveJob继承)