10

MongoDBでmap/reduceジョブを実行するバックグラウンドジョブがあります。ユーザーがドキュメントにさらにデータを送信すると、ドキュメントで実行されているバックグラウンドジョブが開始されます。ユーザーが複数のリクエストを送信すると、同じドキュメントに対して複数のバックグラウンドジョブが開始されますが、実際に実行する必要があるのは1つだけです。複数の重複インスタンスを防ぐ方法はありますか?ドキュメントごとにキューを作成し、新しいジョブを送信する前にキューが空であることを確認することを考えていました。または、ドキュメントIDと同じジョブIDを設定し、送信する前に何も存在しないことを確認できますか?

また、sidekiq-unique-jobsの宝石を見つけました。しかし、ドキュメントは存在しません。これは私が望むことをしますか?

4

4 に答える 4

12

私の最初の提案は、この特定の仕事のミューテックスです。ただし、複数のアプリケーションサーバーがsidekiqジョブを実行している可能性があるため、redisレベルで何かを提案します。

たとえば、sidekiqワーカー定義内で redis-semaphoreを使用します。テストされていない例

def perform
  s = Redis::Semaphore.new(:map_reduce_semaphore, connection: "localhost")

  # verify that this sidekiq worker is the first to reach this semaphore.
  unless s.locked?

    # auto-unlocks in 90 seconds. set to what is reasonable for your worker.
    s.lock(90)
    your_map_reduce()
    s.unlock
  end
end

def your_map_reduce
  # ...
end
于 2013-02-05T18:27:45.300 に答える
6

https://github.com/krasnoukhov/sidekiq-middleware

UniqueJobsジョブに一意性を提供します。

使用法

ワーカーの例:

class UniqueWorker
  include Sidekiq::Worker

  sidekiq_options({
    # Should be set to true (enables uniqueness for async jobs)
    # or :all (enables uniqueness for both async and scheduled jobs)
    unique: :all,

    # Unique expiration (optional, default is 30 minutes)
    # For scheduled jobs calculates automatically based on schedule time and expiration period
    expiration: 24 * 60 * 60
  })

  def perform
    # Your code goes here
  end
end
于 2013-05-31T18:04:07.157 に答える
2

https://github.com/mhenrixon/sidekiq-unique-jobs(SidekiqUniqueJobs )もあります。

于 2015-02-24T16:20:33.413 に答える
0

すべてのジョブがエンキューされたバケットに追加されていると仮定して、これを行うことができます。

class SidekiqUniqChecker
  def self.perform_unique_async(action, model_name, id)
    key = "#{action}:#{model_name}:#{id}"
    queue = Sidekiq::Queue.new('elasticsearch')
    queue.each { |q| return if q.args.join(':') == key }
    Indexer.perform_async(action, model_name, id)
  end
end

上記のコードは単なるサンプルですが、必要に応じて微調整することもできます。

ソース

于 2019-01-12T04:58:21.523 に答える