【问题标题】:Rails 4 Racing/Concurrency. Avoid DeadlockRails 4 竞速/并发。避免死锁
【发布时间】:2015-10-13 17:23:12
【问题描述】:

我目前在 Sidekiq-Unique-Jobs 和 Sidekiq-Status 的帮助下使用 Sidekiq 在我的应用程序上执行任务。

工人执行的工作很小,几乎总是立即执行。 (很少或根本没有队列)

我正在“破解”sidekiq 以同步执行任务(检查Controller can't find object created by worker),这些作业体积小且执行速度快(通常不到 1 秒)。我的应用程序需要同步运行作业并获取其详细信息(创建/更新记录)

使用我正在使用的“蹩脚”解决方案:

  20.times do
    status = Sidekiq::Status::get balance, :exp_status
    if ["done"].include?(status)
      break
    end
    sleep(0.2)
  end

创建一个队列并通过参数(sidekiq-unique-jobs)确保同一用户同时执行不超过 1 个作业我可以避免所有死锁,但是我觉得它应该是执行此操作的更好方法,而不是破解 sidekiq,因为它旨在异步执行工作。

问题是:在我可以限制输入但默认意味着同步运行的方式上,是否有任何替代或类似的 gem 可以替代 sidekiq?我不能只在控制器Balance.find_or_create_by(user: user, market: market) 上询问,因为迟早它会给我带来死锁(同时编辑/操作/创建记录),但我觉得我正在使用的这个 sidekiq 解决方案在长期。我在这里缺少一些基本的东西吗?如何通过中间件或类似的东西确保不会同时执行重复的参数/动作以避免死锁?

【问题讨论】:

  • 您的死锁来自sidekiq,还是您的数据库?或者是其他东西?你是什​​么意思“因为迟早它会让我陷入僵局” - 当它发生时会是什么样子?您从某事中收到错误消息?你得到你不想要的行为? (后者可能不是“死锁”,但可能是竞争条件)。如果这是关于您的数据库竞争条件,那么有一套技术;如果它真的是关于死锁还有另一个。我认为您要问的并不是您想要的,但是如果您解释一下您实际尝试做的事情以及失败的原因..

标签: ruby-on-rails ruby multithreading ruby-on-rails-3 ruby-on-rails-4


【解决方案1】:

你正在破解一个穷人的分布式互斥锁。还有更好的方法。

FOSS

Sidekiq Enterprise's official API

【讨论】:

    【解决方案2】:

    我用Redis-Mutex解决了我的问题。

    有了这个,我有一个本机同步解决方案,它仍然可以锁定我正在处理的行,并且在行锁定的情况下没有问题,因为我通过简单的重试进行救援。当记录解锁时,它会返回并重试工作

      def enter
        RedisMutex.with_lock(user) do
          # hard-work
        end
      rescue RedisMutex::LockError
        retry
      end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-17
      • 1970-01-01
      • 1970-01-01
      • 2020-10-25
      • 2012-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多