Запрос на обновление 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/