2013-09-21 3 views
2

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

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.

+0

Любая вероятность того, что ваш 'id' является большой структурой данных вместо целочисленного значения? – iltempo

+0

Нет, все в порядке. Он просто передает идентификационный номер. –

+0

Выполнение задания синхронно работает так, как ожидалось? 'DrivingStatJob.perform (id)' – iltempo

ответ

0

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

0

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

Вы попадете в Sidekiq::Clients push method. Вот где это становится интересным.

bundle exec sidekiq 

Для 1.9 вы можете использовать debugger gem.

+0

Да, я пробовал отлаживать. Кажется, это даже не делается. Я не уверен, как это работает, возможно, оно застряло в ожидании связи с Redis или чем-то еще. –

0

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

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

Я просто косе сальников идеи здесь ...

0

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

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

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

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

0

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

bundle exec sidekiq -q driving_stats 

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

bundle exec sidekiq -q driving_stats -e production 

или

bundle exec sidekiq -q driving_stats RAILS_ENV=production 

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

Кроме того: вы имеете дело с работником sidekiq в свой родительский или дочерний класс?

class DBJob 
    include Sidekiq::Worker 
end 
Смежные вопросы