ruby-on-rails - 即使超时,Sidekiq worker 仍运行数千秒

标签 ruby-on-rails ruby-on-rails-3 redis semaphore sidekiq

我有一个不应超过 30 秒的 sidekiq worker,但几天后我会发现整个 worker 队列停止执行,因为所有 worker 都被锁定了。

这是我的 worker :

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-信号量 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 秒,工作人员永远不应该运行。

有人对如何解决这个问题或造成它的原因有任何想法吗? worker 们在 EngineYard 上运行。

编辑:一条附加评论。 #DO WORK 有机会触发 PostgresSQL 函数。我注意到在日志中提到了 PG::TRDeadlockDetected: ERROR: deadlock detected。这会导致工作人员即使设置了超时也永远无法完成吗?

最佳答案

鉴于你想确保唯一的作业执行,我会尝试删除所有锁并将作业唯一性控制委托(delegate)给插件,如 Sidekiq Unique Jobs

在这种情况下,即使 sidetiq 将同一个作业 ID 入队两次,此插件也会确保将其入队/处理一次。

关于ruby-on-rails - 即使超时,Sidekiq worker 仍运行数千秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22848655/

相关文章:

ruby - bundle install --deployment 数量错误

ruby-on-rails - Rails-Grails服务等效

ruby-on-rails - 为每个键值对打印散列 View 并换行

ruby-on-rails - Ruby on rails - 辅助方法 - Ruby on rails 中的未定义方法 `log_in'

css - rails 中的背景图像

python - 如何在 Django 中使用 redis?

go - 将结构传递给 redigo Send 函数会破坏它并且数据丢失

python - 使用 conda 的 redis 安装不工作 ModuleNotFoundError 没有名为 'redis' 的模块

ruby-on-rails - 在 Rails 中创建一个简单的计数器

css - 为什么只有当我在按钮上设置背景颜色时字体大小才有效?