我有一个不应该超过30秒的sidekiq工作者,但几天之后我会发现整个工作队列都停止执行,因为所有的工作人员都被锁定了.
这是我的工人:
class MyWorker include Sidekiq::Worker include Sidekiq::Status::Worker sidekiq_options queue: :my_queue, retry: 5, timeout: 4.minutes sidekiq_retry_in do |count| 5 end sidekiq_retries_exhausted do |msg| store({message: "Gave up."}) end def perform(id) begin Timeout::timeout(3.minutes) do got_lock = with_semaphore("lock_#{id}") do # DO WORK end end rescue ActiveRecord::RecordNotFound => e # Handle rescue Timeout::Error => e # Handle raise e end end def with_semaphore(name, &block) Semaphore.get(name, {stale_client_timeout: 1.minute}).lock(1, &block) end end
我们使用的信号量类.(redis-semaphore gem)
class Semaphore def self.get(name, options = {}) Redis::Semaphore.new(name.to_sym, :redis => Application.redis, stale_client_timeout: options[:stale_client_timeout] || 1.hour, ) end end
基本上我会停止工作,它将完成状态:10000秒,工人永远不应该运行.
任何人有任何想法如何解决这个或导致它的原因?工作人员在EngineYard上运行.
编辑:另外一条评论.#DO WORK有机会启动PostgresSQL功能.我在日志中注意到一些提到PG :: TRDeadlockDetected:ERROR:检测到死锁.这是否会导致工作人员即使设置超时也永远不会完成?