单个延迟的工作人员可以在正在进行的工作结束之前开始下一个工作

时间:2016-03-15 09:52:24

标签: ruby-on-rails ruby delayed-job

我在我的应用程序中实现了API速率限制,用于调用第三方API服务,该服务限制了在指定时间间隔内提供服务的请求数。

我经历了延迟的工作文件,找不到我想要的信息。

我的情况是;

如果时间非常短暂,让我们说5秒钟,在2个延迟的工作岗位之间,工人会做什么?

即使第二个作业执行时间到了,它还会等待第一个作业完成,还是会在指定时间内开始作业?

如果是后者,它将打破我的速率限制实施,因为API只让我每分钟60个请求,并且这两个作业将自己限制为每分钟60个请求,并且总共这两个作业将尝试发送大约120个请求一分钟。

提前致谢,欢呼!

2 个答案:

答案 0 :(得分:3)

这取决于可用的DelayedJob工作者的数量。因为免费工作人员会在run_at时间到来之后立即选择工作并进行处理。

如果您需要确保一次只能在作业中运行,我会看到两个简单的选项:

  1. 将您的工作人数限制为1。或者
  2. 将下一个作业列为最后一步处理。
  3. 这可能是这样的:

    class Job
      def process
        # code for the job ... 
    
        # enqueue the next job to run in 5 seconds
        Job.delay(run_at: 5.seconds.from_now).process
      end
    end
    

    第三个选项有点复杂,可以使用named queues。将此类作业排入特殊命名队列后,可以使用该特殊队列计算下一个作业的时间。而不是像这样排队这样的工作:

    Job.delay.process
    

    检查作业是否已存在,如下所示:

    queue_name = 'one_at_a_time'
    latest_job = Delayed::Job.where(queue: queue_name).order(:run_at).last
    run_at     = latest_job ? latest_job.run_at + 5.seconds : Time.current
    Job.delay(queue: queue_name, run_at: run_at).process
    

答案 1 :(得分:0)

另一种选择是每个队列运行一个工作者实例:

RAILS_ENV=production bin/delayed_job --queue=tracking start

RAILS_ENV=production bin/delayed_job --queues=mailers,tasks start

Documentation