Постановка в очередь Delayed_Job с ActiveJobs

В контроллере у меня есть почтовый запрос от аутентифицированного пользователя, запускающего ActiveJob.

RunReportsJob.perform_later(param1, param2, param3)

Работает без ошибок. Но если пользователь снова нажимает кнопку (запрос отправки сообщения), чтобы запустить RunReportsJob, когда он уже запущен, одновременно выполняются 2 задания. Я установил delayed_job, потому что я думал, что это служба очередей, и она будет держать все в одном задании за раз. Но этого не происходит. Ниже моя конфигурация:

# app/jobs/run_reports_job.rb:

class RunReportsJob < ActiveJob::Base
      queue_as :RunReports
      include ShopifyApp::Controller
      # --------------------------------------------------------------
      # JOB ERROR MANAGEMENT
      # --------------------------------------------------------------
      rescue_from(ActiveRecord::RecordNotFound) do |exception|
           # Do something with the exception
           logger.debug "Hit rescue_from"
      end
      # --------------------------------------------------------------
      # JOB FUNCTION
      # --------------------------------------------------------------
      def perform(param1, param2, param3)
        # some code is performed here
      end
 end

# config/application.rb:

config.active_job.queue_adapter = :delayed_job

# config/initializers/delayed_job_config.rb:

Delayed::Worker.max_attempts = 1
Delayed::Worker.max_run_time = 12.hours

person Colin Brogan    schedule 05.07.2016    source источник


Ответы (1)


Вам нужно будет добавить некоторую логику перед RunReportsJob.perform_later(param1, param2, param3), чтобы проверить приоритет задания, уже поставленного в очередь, и увеличить номер приоритета (меньшее число означает более высокий приоритет в соответствии с документацией) в этом примере очередь:

highest_priority = Delayed::Job.where(queue: :RunReports).maximum(:priority)
Delayed::Worker.default_priority = highest_priority + 1 if highest_priority

RunReportsJob.perform_later(param1, param2, param3)

DelayedJob использует таблицу для сохранения информации обо всех заданиях. См. документацию по адресу https://github.com/collectiveidea/delayed_job#gory-details

person neydroid    schedule 05.07.2016
comment
Мне нужно, чтобы второй вызов Job стоял в очереди после первого, а не стрелял в пустоту. Мне кажется, что представленный здесь код ничего не делает, если в очереди уже что-то есть. - person Colin Brogan; 05.07.2016
comment
Может это то, что я ищу?: Delayed::Worker.read_ahead = 1. Если значение по умолчанию равно 5, означает ли это, что delayed_job пытается одновременно запустить последние 5 доступных в своей базе данных? - person Colin Brogan; 05.07.2016
comment
о, теперь я понял, это можно сделать с помощью приоритета, я собираюсь изменить код ответа - person neydroid; 05.07.2016
comment
Neydroid, ваш код работал, заменив следующую строку: Delayed::Worker.default_priority(highest_priority + 1) if highest_priority на Delayed::Worker.default_priority = highest_priority + 1 if highest_priority. Да, документация не ясна. default_priority — это свойство, а не метод установки. Если вы отредактируете свой ответ еще раз с этим изменением, я приму ваш ответ и проголосую за него. - person Colin Brogan; 20.07.2016
comment
отлично, что это сработало с изменением! спасибо за отзыв, уже обновил ответ ???? - person neydroid; 20.07.2016