Как получить доступ к экземпляру отложенного задания внутри Active Job - Rails 4.2

Я использую ActiveJob с delayed_job (4.0.6) в фоновом режиме, и я хочу найти запланированное задание, чтобы удалить его.

Например, если у меня есть

class MyClass

  def my_method
    perform_stuff
    MyJob.set(wait: 1.month.from_now).perform_later(current_user)
  end
end

Затем, если я отредактирую экземпляр MyClass и снова вызову my_method, я хочу отменить это задание и запланировать новое.

Как предлагается в этом посте http://www.sitepoint.com/delayed-jobs-best-practices/, я добавил два столбца в таблицу отложенных заданий:

table.integer :delayed_reference_id
table.string  :delayed_reference_type

add_index :delayed_jobs, [:delayed_reference_id],   :name => 'delayed_jobs_delayed_reference_id'
add_index :delayed_jobs, [:delayed_reference_type], :name => 'delayed_jobs_delayed_reference_type'

Таким образом, я могу найти задержанного Иова и уничтожить его. Но я хотел сделать это внутри класса ActiveJob, чтобы сохранить структуру заданий в моем проекте.

Я хотел сделать что-то вроде:

class MyJob < ActiveJob::Base

  after_enqueue do |job|
    user = self.arguments.first
    job.delayed_reference_id = user.id,
    job.delayed_reference_type = "User" 
  end

  def perform(user)
    delete_previous_job_if_exists(user_id)
  end

  def delete_previous_job_if_exists(user_id)
    Delayed::Job.find_by(delayed_reference_id: 1, delayed_reference_type: 'User').delete
  end
end

Но это не работает.

У кого-нибудь была такая проблема?

2 ответа

Решение

Два изменения: 1. обновлен обратный вызов after_enqueue, так что вы можете обновить таблицу delayed_jobs напрямую 2. исправлена ​​опечатка, где delayed_reference_id был жестко закодирован как 1

Это должно работать:

class MyJob < ActiveJob::Base

  after_enqueue do |job|
    user = self.arguments.first
    delayed_job = Delayed::Job.find(job.provider_job_id)
    delayed_job.update(delayed_reference_id:user.id,delayed_reference_type:'User')
 end

  def perform(user)
    delete_previous_job_if_exists(user.id)
  end

  def delete_previous_job_if_exists(user_id)
    Delayed::Job.find_by(delayed_reference_id: user_id, delayed_reference_type: 'User').delete
  end
end

Если вы хотите получить доступ к Delayed::Job из вашего воркера, в инициализаторе вы можете обезьяны исправить класс JobWrapper.

      module ActiveJob
  module QueueAdapters
    class DelayedJobAdapter
      class JobWrapper
        def perform(job)
        end
      end
    end
  end
end
Другие вопросы по тегам