создать повторяющуюся активную работу не удается

Я пытаюсь создать ActiveJob в rails 4.2, который работает с обычной скоростью. Задание вызывается в первый раз, но не запускается снова. Мой код выдает исключение ниже после попытки вызова Perform_later.

вывод журнала

[ActiveJob] Enqueued ProcessInboxJob (Job ID: 76a63689-e330-47a1-af92-8e4838b508ae) to Inline(default)
[ActiveJob] [ProcessInboxJob] [76a63689-e330-47a1-af92-8e4838b508ae] Performing ProcessInboxJob from Inline(default)
ProcessInboxJob running...
[ActiveJob] [ProcessInboxJob] [76a63689-e330-47a1-af92-8e4838b508ae] [AWS S3 200 0.358441 0 retries] list_objects(:bucket_name=>"...",:max_keys=>1000)  

[ActiveJob] [ProcessInboxJob] [76a63689-e330-47a1-af92-8e4838b508ae] Enqueued ProcessInboxJob (Job ID: dfd3dd7a-06ab-4dba-9bbf-ce1ad606f7e5) to Inline(default) with arguments: {:wait=>30 seconds}
[ActiveJob] [ProcessInboxJob] [76a63689-e330-47a1-af92-8e4838b508ae] Performed ProcessInboxJob from Inline(default) in 599.72ms
Exiting
/Users/antarrbyrd/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/activejob-4.2.0/lib/active_job/arguments.rb:60:in `serialize_argument': Unsupported argument type: ActiveSupport::Duration (ActiveJob::SerializationError)

process_inbox_job.rb

class ProcessInboxJob < ActiveJob::Base
  queue_as :default
  #FREQUENCY = 3.minutes
  def perform()
    # do some work
  end
  # reschedule job
  after_perform do |job|
    self.class.perform_later(wait: 30.seconds)
  end
end

person Antarr Byrd    schedule 13.01.2015    source источник
comment
Вы уверены, что должны звонить .perform после звонка .perform_later?   -  person ptd    schedule 13.01.2015
comment
@ptd довольно внимательно смотрит на документацию по драгоценному камню. Удаление также не меняет результат   -  person Antarr Byrd    schedule 13.01.2015


Ответы (3)


Синтаксис: self.class.set(wait: 30.seconds).perform_later. Но это ненадежный способ сделать это, как если бы произошло исключение, цепочка обрывается. Также у вас должна быть запланирована начальная работа. Если вы используете resque, вы можете использовать https://rubygems.org/gems/activejob-scheduler.

person Cristian Bica    schedule 13.01.2015
comment
Выполнение с self.class.set приводит к нереализованной ошибке active_job/queue_adapters/inline_adapter.rb:18:in enqueue_at': используйте бэкенд очередей для постановки заданий в очередь в будущем. Подробнее читайте на странице guides.rubyonrails.org/v4.2.0/active_job_basics.html. (Нереализованная ошибка)` - person Antarr Byrd; 13.01.2015
comment
Вам нужно будет использовать другой адаптер, так как встроенный адаптер не поддерживает планирование заданий, которые будут выполняться позже. - person Cristian Bica; 13.01.2015

Как сказал @bcd, вы должны использовать self.class.set(wait: 30.seconds).perform_later с адаптером очереди, поддерживающим организацию очереди, то есть не с адаптером по умолчанию (встроенным).

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

after_perform не будет вызываться, если возникнет исключение, но это не не делает перепланирование задания неправильным местом. Если у вас есть исключение в задании, лучше спасите его (с помощью метода класса rescue_from) и отправьте себе уведомление, если ваш сервер еще не сделал этого.

Затем вы можете попытаться исправить проблему (либо в данных, либо в вашем коде) и повторить попытку (если сможете) или снова поставить в очередь аналогичное задание.

Что касается планирования, activejob-scheduler великолепен и работает не только для восстановления, но и имеет некоторые недостатки.

Он использует rufus-scheduler, который выполняет задержку в памяти, поэтому всякий раз, когда ваш сервер перезагружается, вы теряете всю информацию о планировании, что действительно может быть проблемой для некоторых задач (я планирую задачи на 1 месяц в будущем и обновляю свое приложение каждую неделю , что означает перезапуск каждый раз).

Вы также теряете все преимущества использования реального бэкэнда очередей, такого как beanstalk с backburner.

ActiveJob-scheduler также утверждает, что выполняет задание точно в нужное время, что неверно. Адаптер ActiveJob запускается в указанное время, но в зависимости от ваших настроек может пройти некоторое время, прежде чем задание действительно будет выполнено, например. когда вы запускаете свои задания на другом сервере.

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

Подводить итоги,

Да, ActiveJob-Scheduler великолепен, но вы потеряете некоторые функции ActiveJob, и он не может делать все.

person Geoffroy    schedule 20.04.2015

в зависимости от того, какую систему очередей вы используете, вы можете попробовать https://github.com/codez/delayed_cron_job или https://github.com/ondrejbartas/sidekiq-cron. С DJ cron вы можете использовать пользовательский интерфейс, такой как rails_admin, для фактического редактирования регулярного выражения cron. Sidekiq-cron предоставляет вам веб-интерфейс Sinatra, где вы можете вручную запустить задание или приостановить его.

person Dmitry Polyakovsky    schedule 27.01.2016