AKKI
AKKI

Reputation: 83

Delayed Job inserts every request twice into the backend?

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

Answers (3)

Hyrum Carlile
Hyrum Carlile

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

jox
jox

Reputation: 2368

There are two options:

  1. Do not inherit the job from ActiveJob::Base and trigger it with:

    Delayed::Job.enqueue SomeJob.new(args)

or

  1. 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

mltsy
mltsy

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

Related Questions