1

在我的 Rails 3.2 项目中,我使用SuckerPunch在创建/更新模型时运行昂贵的后台任务。

用户可以在此模型上进行不同类型的交互。大多数时候,这些更新的间隔非常好,但是对于一些其他操作,如重新排序、批量更新等,这些 POST 请求可能会非常频繁地出现,这就是它压倒服务器的时候。

我的问题是,当第一次更新发生时启动后台作业的最优雅/最智能的策略是什么,但是等待10 秒以确保没有更多更新进入该模型(表,而不是一行),然后执行作业。如此有效地节流而无需排队。

我的sucker_punch工人看起来像这样:

class StaticMapWorker
    include SuckerPunch::Job
    workers 10

    def perform(map,markers)
        #perform some expensive job
    end
end

它从Marker“映射”模型中调用,有时从控制器(对于update_all案例)中调用,如下所示:

after_save :generate_static_map_html

def generate_static_map_html
    StaticMapWorker.new.async.perform(self.map, self.map.markers)
end

因此,运行后台作业的一个非常标准的设置。如何让工作等待或不安排,直到x seconds我的模型(或表)上没有更新

如果有帮助,地图 has_many 标记会通过逻辑触发这项工作,以至于当地图更新的任何标记关联也可以。

4

1 回答 1

1

您正在寻找的是通过 ActiveJob 实现的延迟工作perform_later。根据边缘指南,这没有在sucker_punch.
ActiveJob::QueueAdapters比较

但是,不要担心,因为您可以非常简单地自己实现它。当您的作业从队列中检索作业时,首先对记录modified_at时间戳执行一些数学运算,将其与 10 秒前进行比较。如果模型已被修改,只需将作业添加到队列并优雅地中止。

代码!

按照页面下方 2/5 的示例,解释如何在工作人员Github 吸盘冲头中添加工作

class StaticMapWorker
  include SuckerPunch::Job
  workers 10

  def perform(map,markers)
    if Map.where(modified_at: 10.seconds.ago..Time.now).count > 0
      StaticMapWorker.new.async.perform(map,markers)
    else
      #perform some expensive job
    end
  end
end
于 2015-12-30T13:44:07.307 回答