Запрос на обновление delayed_job выполняется бесконечно

Я использую delayed_job и delayed_job_active_record для фонового выполнения задания в моем приложении rails. Мы используем очередь на основе delayed_job. Для запуска с задержкой я использую следующую команду.

RAILS_ENV=staging script/delayed_job -i=1 --queue=queue_name start

Проблема ниже, запрос стреляет бесконечно.

SQL (0.4ms)  UPDATE 'delayed_jobs' SET 'locked_at' = '2013-04-16 09:27:23', 'locked_by' = 'delayed_job.=2 host:ip-10-204-210-77 pid:2168' WHERE 'delayed_jobs'.'queue' IN ('queue_name') AND ((run_at <= '2013-04-16 09:27:23' AND (locked_at IS NULL OR locked_at < '2013-04-16 05:27:23') OR locked_by = 'delayed_job.=2 host:ip-10-204-210-77 pid:2168') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1

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

Ответ 1

Я думаю, что вы имели в виду, что опрос delayed_job слишком часто (кстати, это каждый раз 5 секунды по умолчанию). Я знаю, что заполняет ваш журнал и кажется "бесконечным"..:)

Если это то, что вы имели в виду, тогда я предлагаю вам запустить безошибочный камень. Он начнет запускать delayed_job на основе потребности. Многие люди используют его, чтобы поддерживать Heroku рабочих динозавров в режиме ожидания, но он работает так же хорошо в режиме development.

Обратите внимание: если вы используете delayed_job_active_record, вам также нужно добавить gem 'daemons' к вашему Gemfile (daemons). См. Раздел Запуск заданий delayed_job.

Таким образом, ваш Gemfile будет содержать:

gem 'delayed_job_active_record'
gem 'daemons'
gem 'workless'

Если вам нужно больше рекомендаций, дайте мне знать в комментариях ниже.

Ответ 2

Мне пришлось использовать AR silence метод, просто измените файл [path/to/delayed_job_active_record/gem]/delayed_job_active_record-[any.latest.version]/lib/delayed/backend/active_record.rb на строку 68:

count = ready_scope.limit(1).update_all(:locked_at => now, :locked_by => worker.name)

to

count = silence {ready_scope.limit(1).update_all(:locked_at => now, :locked_by => worker.name)}

грязное решение, но я знаю, но оно работает... добро пожаловать предложить лучшую оболочку, но для меня метод Job.reserve существует достаточно большой, чтобы убить любые мысли, чтобы переопределить его в config/initializers

Ответ 3

Итак, это запрос, специально предназначенный для Postgres. Пожалуйста, обратитесь к https://github.com/collectiveidea/delayed_job_active_record/blob/master/lib/delayed/backend/active_record.rb#L57 за то, почему это должно быть так.

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

Работаете ли вы на очень ограниченном оборудовании, таком как очень маленькая виртуальная машина?

Ответ 4

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

def self.up
  create_table :delayed_jobs, :force => true do |table|
  # Add index on queue field
  add_index :delayed_jobs, [:queue], :name => 'delayed_jobs_queue'
end

Для получения дополнительной информации посетите ниже документ http://himarsh.org/cautions-on-delayed-jobs/