Подтвердить что ты не робот

Как отменить запланированную работу с delayed_job в Rails?

Я планирую задание работать в 10 минут. Как правильно отменить эту конкретную работу без использования каких-либо грязных дополнительных полей в модели и т.д. Есть ли какой-либо вызов для удаления определенного задания или заданий, связанных с конкретной моделью, экземпляром и т.д.?

4b9b3361

Ответ 1

отказ от ответственности: я не являюсь опытным пользователем delayed_job...

"Есть ли какой-либо вызов для удаления определенного задания или заданий, связанных с конкретной моделью, экземпляром и т.д.?

Delayed:: Job - это объект ActiveRecord, поэтому вы можете найти и уничтожить любую из этих записей. В зависимости от вашего варианта использования это можно обрабатывать по-разному. Если кто-то собирается их вручную уничтожить, это может быть обработано через интерфейс администратора в вашем веб-приложении.

# list all jobs
Delayed::Job.all
# find a job by id
job = Delayed::Job.find(params[:id])
# delete it
job.delete

если вам нужно, чтобы какая-то из задач процесса удаляла задания по типу задания, вы могли бы прокручивать каждую из них и удалять ее, если она соответствует вашей задаче; попробуйте в script/console

class MyJob < Struct.new(:some_value);
    def perform
        # ...
    end
end

my_job = MyJob.new('xyz')
job = Delayed::Job.enqueue(my_job, 0, 1.hour.from_now)
job.name
# => "MyJob"
job.handler
# => "--- !ruby/struct:MyJob \nsome_value: xyz\n"

так что дано выше, если вы хотите удалить все задания типа MyJob

Delayed::Job.all.each do |job|
    if job.name == "MyJob" then
        job.delete
    end
end

Это может или не поможет вам в вашей ситуации? во многих случаях вы можете удалить MyJob, но только там, где атрибут: some_value был "abc", а не "xyz". В этом случае вам может потребоваться реализовать "display_name" на вашем объекте MyJob. job.name будет использовать это, если оно существует

class MyJob < Struct.new(:user_id);
    def perform
        # ...
    end

    def display_name
        return "MyJob-User-#{user_id}"
    end 
end

# store reference to a User
my_job = MyJob.new(User.first.id) # users.id is 1
job = Delayed::Job.enqueue(my_job, 0, 1.hour.from_now)
job.name
# => "MyJob-User-1"
job.handler
# => "--- !ruby/struct:MyJob \nuser_id: 1\n"

Таким образом, вы можете быть более избирательным, какие записи удалить?

надеюсь, это даст вам достаточно информации о возможных способах его решения?

Ответ 2

delayed_job 3 введен атрибут queue. Это можно угнать, чтобы запланировать отмену задания.

class MyJob < Struct.new(:user_id)
  def self.queue_name
    "something-unique"
  end

  def perform
    # ...
  end
end

#scheduler
my_job = MyJob.new(User.first.id)
#'cancel' pending jobs first
Delayed::Job.where(queue: my_job.class.queue_name).destroy_all
#queue it up
Delayed::Job.enqueue(my_job,
  queue: my_job.class.queue_name,
  run_at: 1.hour.from_now
)

Ответ 3

Вы можете также рассмотреть возможность использования метода payload_object с отложенным заданием, если вы ищете задание только по переданному параметру.

Delayed::Job.all.each do |job|
  job.destroy if job_corresponds_to_target?(job, target)
end

def job_corresponds_to_target?(job, target)
  job.payload_object.args.first == target.id
end

Этот упрощенный пример не использует полностью возвращенный payload_object:

=> #<Delayed::PerformableMethod:0x0056551eae3660 @object=ReminderMailJob, @method_name=:perform_later, @args=[3]>