Sidekiq зависает приложение

Итак, у меня есть код, часть задачи rake:

  class DrivingStatJob < DBJob
  sidekiq_options :queue => :driving_stats, :backtrace => true

  def perform(work_order_id)
    Rails.logger.info "Calculating driving stats for work_order #{work_order_id}"
    begin
      work_order = WorkOrder.find(work_order_id)
      return unless work_order.steps.size > 1
      DrivingStat.calculate!(work_order.steps.first.location.address, work_order.steps.last.location.address)
    rescue DrivingStatService::MissingCoordinatesError
      Rails.logger.warn "Unable to fetch coorindates for work order #{work_order_id}"
    rescue ActiveRecord::RecordInvalid => e
      Rails.logger.warn "Unable to save driving stat: #{e.message}"
    rescue ActiveRecord::RecordNotFound
      # Ignore
    rescue RuntimeError => e
      Rails.logger.warn "Unable to compute driving directions"
      Rails.logger.warn [e.message, e.backtrace].join("\n")
    end
  end
end

Код, который вызывает «выполнение»:

begin
  DrivingStatJob.perform_async(id) if changed
rescue Redis::CannotConnectError => e
  logger.warn "Unable to queue up driving stats job"
  logger.warn [e.message, e.backtrace].join("\n")
end

Проблема: зависает на DrivingStatJob.perform_async(id). Просто висит без ошибок. Нет сообщений журнала от функции «выполнить». Что это может быть? Redis работает без ошибок, sidekiq работает без ошибок. Redis работает на 127.0.0.1:6379, Sidekiq показывает, что знает, что Redis там есть.

Linux Mint 15, Ruby 1.9.3, Redis 2.6, sidekiq-2.14.


person Eugene Demidov    schedule 21.09.2013    source источник
comment
Есть ли шанс, что ваш id представляет собой большую структуру данных, а не целочисленное значение?   -  person iltempo    schedule 21.09.2013
comment
Нет, с ним все в порядке. Он просто передает идентификационный номер.   -  person Eugene Demidov    schedule 21.09.2013
comment
Синхронный запуск задания работает должным образом? DrivingStatJob.perform(id)   -  person iltempo    schedule 21.09.2013
comment
Да, изменил его на self.perform, и он отлично работает. У меня есть подозрение, что проблема может быть из-за того, что что-то работает неправильно — Redis или sidekiq. Хотя я понятия не имею, что, они все молчат, как будто ничего страшного не произошло.   -  person Eugene Demidov    schedule 22.09.2013


Ответы (5)


Трудно сказать, что происходит. Чтобы узнать это, поместите debugger в метод выполнения и запустите воркер sidekiq на переднем плане. Это дает вам возможность пройтись по методам.

Вы окажетесь в методе Sidekiq::Clients push< /а>. Вот где становится интересно.

bundle exec sidekiq

Для версии 1.9 вы можете использовать жем отладчика.

person iltempo    schedule 22.09.2013
comment
Да пробовал отлаживать. Кажется, даже до этого момента не доходит. Я не уверен, как это работает, может быть, он застрял в ожидании соединения с Redis или что-то в этом роде. - person Eugene Demidov; 22.09.2013

Можете ли вы получить доступ к маршрутам для sidekiq из вашей задачи rake? Попробуйте это из контроллера, чтобы увидеть, связано ли это с задачей rake. Возможно, вам не хватает include или require. Если избавиться от блока восстановления, он вылетает и выдает ошибку?

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

Я просто плюю сюда идеями...

person penner    schedule 23.09.2013

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

Если вы используете rails, вы можете добавить это в свой файл route.rb, чтобы иметь возможность исследовать очереди sidekiq.

require 'sidekiq/web'
mount Sidekiq::Web, at: '/sidekiq'

Если вы видите задание в очередях sidekiq, вам придется запустить работника для обработки выполнения. Если задания нет, вы должны проверить соединение с Redis.

person Toon    schedule 24.09.2013

Если вы планируете задания в любой очереди, кроме очереди по умолчанию, вам необходимо явно указать имя очереди при запуске sidekiq.

bundle exec sidekiq -q driving_stats

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

bundle exec sidekiq -q driving_stats -e production

or

bundle exec sidekiq -q driving_stats RAILS_ENV=production

Если это по какой-то причине не работает, выньте sidekiq_options полностью и запустите его в очереди по умолчанию с помощью простого

bundle exec sidekiq

Также: вы включаете sidekiq worker в свой родительский или дочерний класс, верно?

class DBJob
  include Sidekiq::Worker
end
person thrice801    schedule 28.09.2013

Проблема была в конфигурации Redis. Он использовал Sentinel, отключение Sentinel для разработки решило эту проблему.

person Eugene Demidov    schedule 29.09.2013
comment
Любой намек на то, почему это решило проблему, или что заставило вас поверить, что его отключение сработает? - person Abe Petrillo; 14.02.2019