Active Job — Как отменить запланированное задание Action Mailer?


person Alexander    schedule 26.01.2016    source источник


Ответы (2)


Я решил подойти к проблеме иначе. Вместо того, чтобы планировать работу и уничтожать ее, я просто планирую работу.

Когда пользователь устанавливает напоминание на три дня вперед, создается задание, как и раньше. Если пользователь удалит напоминание по электронной почте, задание все равно будет выполняться через три дня, но ничего не произойдет. Вот пример настройки:

# controllers/users_controller.rb

def schedule_reminder
  # Get the user that scheduled the reminder
  user = User.find_by_id(params[:id])

  # Create a reminder for the user
  reminder = user.reminders.create(active: true)

  # Schedule the reminder to be sent out
  SendReminderJob.set(wait_until: 3.days.from_now).perform_later(reminder.id)
end

def unschedule_reminder
  reminder = Reminder.find_by_id(params[:reminder_id])

  reminder.destroy
end

Когда пользователь планирует напоминание, выполняется def schedule_reminder. Этот метод создает напоминание и планирует задание, которое будет выполняться через 3 дня. Он передает идентификатор напоминания в качестве аргумента, чтобы задание могло получить напоминание при запуске.

Когда пользователь удаляет напоминание, выполняется def unschedule_reminder. Этот метод находит напоминание и удаляет его.

Вот как выглядит моя SendReminderJob работа:

# jobs/send_reminder_job.rb

class SendReminderJob < ActiveJob::Base
  queue_as :default

  def perform(*args)
    # Get the reminder
    # args.first is the reminder ID
    reminder = Reminder.find_by_id(args.first)

    # Check if the reminder exists
    if !reminder.nil?
      # Send the email to the user

    end
  end
end

Когда это задание выполняется через три дня, оно проверяет, установлено ли еще напоминание. Если это так, он отправляет электронное письмо пользователю. В противном случае он ничего не делает. Независимо от того, делает она что-нибудь или нет, эта работа удаляется через три дня!

person Alexander    schedule 05.02.2016

Я создал app/models/delayed_backend_mongoid_job.rb.

class DelayedBackendMongoidJob
  include Mongoid::Document    
  field :priority,      type: Integer
  field :attempts,      type: Integer
  field :queue,         type: String
  field :handler,       type: String
  field :run_at,        type: DateTime
  field :created_at,    type: DateTime
  field :updated_at,    type: DateTime
end

Если вы используете ActiveRecord, вам необходимо настроить файл модели. Затем я установил rails_admin и могу просматривать/редактировать любые записи в этой таблице.

Если у вас запланирована работа через 2 дня, все, что вам нужно сделать, это удалить запись, и DJ никогда ее не возьмет.

person Dmitry Polyakovsky    schedule 27.01.2016
comment
Спасибо за Ваш ответ! Как мне найти правильную запись для удаления, если моя таблица отложенных заданий заполнена похожими заданиями? - person Alexander; 27.01.2016
comment
Вы можете использовать именованные очереди, чтобы затем фильтровать их в rails_admin. Или вы можете добавить поле rails_admin с форматированным_значением :handler. Или добавьте в свою модель метод для захвата параметров из обработчика и фильтрации по параметрам в RA. - person Dmitry Polyakovsky; 27.01.2016
comment
Я не использую rails_admin и хотел бы автоматически отменить задание, как только пользователь удалит напоминание по электронной почте. Как вы думаете, именованные очереди все еще будут работать? Мне нужно получить точное напоминание по электронной почте, чтобы удалить его, и мне нецелесообразно проходить через интерфейс и удалять их вручную. - person Alexander; 28.01.2016
comment
:handler должен иметь какой-то уникальный идентификатор для вашей электронной почты, так как это необходимо для работы. Найдите запись и удалите ее. stackoverflow.com/questions/3638250/ - person Dmitry Polyakovsky; 28.01.2016