Ruby on rails 使用sidekiq只执行多个重复作业中的一个?

Ruby on rails 使用sidekiq只执行多个重复作业中的一个?,ruby-on-rails,mongodb,sidekiq,Ruby On Rails,Mongodb,Sidekiq,我有一个后台工作,在MongoDB上做映射/减少工作。当用户向文档发送更多数据时,它将启动在文档上运行的后台作业。如果用户发送多个请求,它将启动同一文档的多个后台作业,但实际上只需要运行一个。是否有一种方法可以防止多个重复实例?我在考虑为每个文档创建一个队列,并在提交新作业之前确保它是空的。或者我可以设置一个与我的文档id相同的作业id,并在提交之前检查是否不存在 另外,我刚刚发现了一个sidekiq独特的工作宝石。但文件是不存在的。这符合我的要求吗?我最初的建议是为这个特定的工作提供一个互斥器

我有一个后台工作,在MongoDB上做映射/减少工作。当用户向文档发送更多数据时,它将启动在文档上运行的后台作业。如果用户发送多个请求,它将启动同一文档的多个后台作业,但实际上只需要运行一个。是否有一种方法可以防止多个重复实例?我在考虑为每个文档创建一个队列,并在提交新作业之前确保它是空的。或者我可以设置一个与我的文档id相同的作业id,并在提交之前检查是否不存在


另外,我刚刚发现了一个sidekiq独特的工作宝石。但文件是不存在的。这符合我的要求吗?

我最初的建议是为这个特定的工作提供一个互斥器。但是,由于有可能有多个应用服务器在处理sidekiq任务,我建议在redis级别进行一些操作

例如,在sidekiq worker定义中使用。一个未经测试的例子:

def执行
新(:map\u reduce\u信号量,连接:“localhost”)
#验证此sidekiq工作者是第一个到达此信号量的人。
除非s锁上了?
#自动解锁时间为90秒。设置为对您的员工合理的值。
s、 锁(90)
你的地图
s、 解锁
结束
结束
定义你的地图
# ...
结束

独一无二的工作 为作业提供唯一性

用法

示例工人:

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

还有(SidekiqUniqueJobs)。

您可以这样做,假设您已经将所有作业添加到排队桶中

class SidekiqUniqChecker
定义self.perform_unique_async(操作、型号名称、id)
key=“#{action}:#{model_name}:#{id}”
queue=Sidekiq::queue.new('elasticsearch')
queue.each{| q |如果q.args.join(':')==key}返回
Indexer.perform\u async(操作、模型名称、id)
结束
结束
上面的代码只是一个示例,但您可以根据需要对其进行调整


我想到了另一种方法,我可以在文档上设置一个要更新的字段,并让后台作业在完成时将其清除。然后,只有在字段清楚的情况下才安排后台任务。有多少服务器正在运行这些sidekiq作业?顺便问一下,我使用redis mutex来完成这个任务,但基本上是相同的想法。太棒了!我不知道有redis互斥软件包。但我同意在这种情况下,互斥是合适的工具。@crftr这个解决方案对您有何帮助?对其他有相同问题的人的任何建议。