Reputation: 83
I have an Rails 5 Application wherein it makes use of Delayed Job to fetch data from an external API and save it on a DB store,
However, when I place a request for the seeding to be done from the API, it queues in the same seed request twice instead of treating it once.
Upon initial observation, I do see that the handlers for the two records are quite different from the other. Posted below are snippets of my code that i have tried.
Need to understand as to why this could be happening. Any help sought would be much appreciated. Thanks in advance.
Controller Code
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
Delayed Job Table Records After enqueuing the request.
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"]]
Notice the change in the handler attributes of the two records that have been created.
Upvotes: 4
Views: 681
Reputation: 117
If you want to keep the job inheriting from ActiveJob::Base
, you can enqueue it with Active Job's syntax like so:
MyJob.new(params).enqueue
instead of:
Delayed::Job.enqueue Myjob.new(params)
This will only enqueue it once and it will still be processed by Delayed::Job
Upvotes: 1
Reputation: 2368
There are two options:
Do not inherit the job from ActiveJob::Base
and trigger it with:
Delayed::Job.enqueue SomeJob.new(args)
or
Do inherit the job from ActiveJob::Base
and trigger it with:
SomeJob.perform_later(args)
(But when inheriting from ActiveJob::Base
and using Delayed::Job.enqueue
at the same time, it will trigger the job twice, as explained by mltsy).
Upvotes: 2
Reputation: 7084
Aha!
Hooks: https://github.com/collectiveidea/delayed_job#hooks
Delayed::Job has an enqueue hook that calls the enqueue
method on your Job class when it is enqueued. If your job happens to be an ActiveJob, this will trigger the enqueue method defined by the ActiveJob::Base class, which actually queues the job again! (This time as an activejob)
Solution: If you're creating a custom job that you're going to enqueue by calling Delayed::Job.enqueue, don't inherit from ActiveJob! Just use a plain old Ruby object with a perform
method. (Alternately, you could override the enqueue
method with one that does nothing, but there's no need to inherit from ActiveJob in the first place really)
Upvotes: 3