Ruby on rails 单个延迟的工作人员能否在正在进行的工作结束之前开始下一个工作?

Ruby on rails 单个延迟的工作人员能否在正在进行的工作结束之前开始下一个工作?,ruby-on-rails,ruby,delayed-job,Ruby On Rails,Ruby,Delayed Job,我在调用第三方API服务的应用程序中实现了API速率限制,它限制了在指定时间间隔内对服务的请求数量 我查阅了延迟的工作文件,找不到我想要的信息 我的情况是 如果两个延迟的工作之间的时间真的很短,比如说5秒,工人会怎么做 即使第二个作业执行时间已到,它还是会等待第一个作业完成,还是会在指定时间启动作业 如果是后者,它将打破我的速率限制实现,因为API只允许我每分钟发送60个请求,并且两个作业将自己限制为每分钟60个请求,总的来说,两个作业将尝试在一分钟内发送大约120个请求 提前谢谢,干杯 这取决

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

我查阅了延迟的工作文件,找不到我想要的信息

我的情况是

如果两个延迟的工作之间的时间真的很短,比如说5秒,工人会怎么做

即使第二个作业执行时间已到,它还是会等待第一个作业完成,还是会在指定时间启动作业

如果是后者,它将打破我的速率限制实现,因为API只允许我每分钟发送60个请求,并且两个作业将自己限制为每分钟60个请求,总的来说,两个作业将尝试在一分钟内发送大约120个请求


提前谢谢,干杯

这取决于可用的延迟工作人员的数量。因为一个自由工作者会在时间的
运行时选择一个作业并处理它

如果您需要确保一次仅在作业上运行,我将看到两个简单的选项:

  • 将员工数量限制在
    1
    。或
  • 将下一个作业排队作为处理的最后一步
  • 可能是这样的:

    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
    
    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
    
    第三个选项有点复杂,可以使用。当您将此类作业排队到一个特殊的命名队列中时,您可以使用该特殊队列来计算下一个作业的时间。而不是像这样将作业排队:

    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
    
    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
    
    检查作业是否已存在,如下所示:

    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
    
    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
    。或
  • 将下一个作业排队作为处理的最后一步
  • 可能是这样的:

    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
    
    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
    
    第三个选项有点复杂,可以使用。当您将此类作业排队到一个特殊的命名队列中时,您可以使用该特殊队列来计算下一个作业的时间。而不是像这样将作业排队:

    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
    
    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
    
    检查作业是否已存在,如下所示:

    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
    
    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
    

    另一个选项是为每个队列运行一个worker实例:

    RAILS\u ENV=production bin/delayed\u job--queue=tracking start

    RAILS\u ENV=production bin/delayed\u job--queues=mailer,tasks start


    另一个选项是为每个队列运行一个worker实例:

    RAILS\u ENV=production bin/delayed\u job--queue=tracking start

    RAILS\u ENV=production bin/delayed\u job--queues=mailer,tasks start


    感谢您的快速回复!我已经将工人数减少到1,如果我理解正确,这就足够了,对吗?工人将忙于第一项工作,只有在第一项工作完成后才开始第二项工作?“将下一个作业排队作为处理的最后一步。”你能详细说明一下吗?在我的应用程序中,用户是安排作业的人,因此无法知道他们何时计划作业。是的,将workers减少到1将确保一次只运行一个作业。我不知道用户在你的应用程序中安排作业。在这种情况下,第二个版本不起作用。但可能还有另一种选择。我将在几分钟内更新我的答案…非常感谢您的详细解释,我认为您在那里做的是第三个选项,这可以工作,但它需要一点不同的实现。因为最后一份工作并不总是与我们即将创建的工作冲突的,对吗?用户可以将作业安排在下个月,也可以将其安排在第二天。例如,我需要检查他之前和接下来的10秒,以查看是否存在任何潜在冲突。但现在我想我会选择单身工人。谢谢你的快速回复!我已经将工人数减少到1,如果我理解正确,这就足够了,对吗?工人将忙于第一项工作,只有在第一项工作完成后才开始第二项工作?“将下一个作业排队作为处理的最后一步。”你能详细说明一下吗?在我的应用程序中,用户是安排作业的人,因此无法知道他们何时计划作业。是的,将workers减少到1将确保一次只运行一个作业。我不知道用户在你的应用程序中安排作业。在这种情况下,第二个版本不起作用。但可能还有另一种选择。我将在几分钟内更新我的答案…非常感谢您的详细解释,我认为您在那里做的是第三个选项,这可以工作,但它需要一点不同的实现。因为最后一份工作并不总是与我们即将创建的工作冲突的,对吗?用户可以将作业安排在下个月,也可以将其安排在第二天。例如,我需要检查他之前和接下来的10秒,以查看是否存在任何潜在冲突。但现在我想我会和一个工人一起去。除此之外,在工作完成后,它还会运行另一个吗?@VishwasNahar Yea。如果每个队列有一个工人。还要确保每个dj工作人员都指定了一个队列,因为在没有指定队列的情况下启动的工作人员将从任何队列运行作业。当然,但在我的情况下,我有100个位置,其中延迟的作业调用我不能只为该作业分配一个工作人员,而不是在作业完成后,它只运行另一个?@VishwasNahar Yea。如果每个队列有一个工人。还要确保每个dj工作者都指定了一个队列,因为在没有指定队列的情况下启动的工作者将重新启动