Gee*_*esu 5 semaphore ruby-on-rails redis ruby-on-rails-3 sidekiq
我有一个不应该超过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
Run Code Online (Sandbox Code Playgroud)
我们使用的信号量类.(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
Run Code Online (Sandbox Code Playgroud)
基本上我会停止工作,它将完成状态:10000秒,工人永远不应该运行.
任何人有任何想法如何解决这个或导致它的原因?工作人员在EngineYard上运行.
编辑:另外一条评论.#DO WORK有机会启动PostgresSQL功能.我在日志中注意到一些提到PG :: TRDeadlockDetected:ERROR:检测到死锁.这是否会导致工作人员即使设置超时也永远不会完成?
鉴于您希望确保唯一的作业执行,我会尝试删除所有锁定并将作业唯一性控制委托给像Sidekiq Unique Jobs这样的插件
在这种情况下,即使 sidetiq 将相同的作业 ID 排队两次,该插件也确保它将被排队/处理一次。
| 归档时间: |
|
| 查看次数: |
2100 次 |
| 最近记录: |