有办法通过Rails代码告诉一个正在睡眠的延迟作业工作者来处理队列吗?

huangapple go评论63阅读模式
英文:

Is there a way to tell a sleeping delayed job worker to process the queue from Rails code?

问题

I'm using delayed_job library as adapter for Active Jobs in Rails:

config.active_job.queue_adapter = :delayed_job

My delayed_job worker is configured to sleep for 60 seconds before checking the queue for new jobs:

Delayed::Worker.sleep_delay = 60

In my Rails code I add a new job to the queue like this:

MyJob.perform_later(data)

However, the job will not be picked up by the delayed_job worker immediately, even if there are no jobs in the queue, because of the sleep_delay. Is there a way to tell the delayed_job worker to wake up and start processing the job queue if it's sleeping?

There is a MyJob.perform_now method, but it blocks the thread, so it's not what I want because I want to execute a job asynchronously.

英文:

I'm using delayed_job library as adapter for Active Jobs in Rails:

config.active_job.queue_adapter = :delayed_job

My delayed_job worker is configured to sleep for 60 seconds before checking the queue for new jobs:

Delayed::Worker.sleep_delay = 60

In my Rails code I add a new job to the queue like this:

MyJob.perform_later(data)

However, the job will not be picked up by the delayed_job worker immediately, even if there are no jobs in the queue, because of the sleep_delay. Is there a way to tell the delayed_job worker to wake up and start processing the job queue if it's sleeping?

There is a MyJob.perform_now method, but it blocks the thread, so it's not what I want because I want to execute a job asynchronously.

答案1

得分: 1

看着 delayed_job 的代码,似乎没有办法在它们被设为守护进程后直接控制或与工作进程通信。

我认为你能做的最好的办法是启动一个单独的工作进程,它具有较小的 sleep_delay,只读取特定的队列,然后将该队列用于这些工作。需要单独的命令,因为你不能启动一个工作池,其中的工作进程具有不同的休眠延迟:

  1. 启动主工作进程:bin/delayed_job start
  2. 启动快速工作进程:bin/delayed_job start --sleep-delay=5 --queue=fast --identifier=999(标识符是必要的,以区分工作进程守护程序)
  3. 更新你的工作以使用该队列:
class MyJob < ApplicationJob
  queue_as :fast

  def perform...
end

注意:

  • 当你想要停止工作进程时,你也必须分开做:bin/delayed_job stopbin/delayed_job stop --identifier=999

  • 这引入了一些潜在的并行性和在两个工作进程同时运行时对服务器的额外负载。

  • 主工作进程也会处理来自 fast 队列的工作,只是看哪个工作进程先抓到了工作。如果你不想要这样,你需要设置主工作进程只从其他队列中读取,默认情况下只有 'default' 队列,所以:bin/delayed_job start --queue=default

英文:

Looking at the delayed_job code and it appears that there's no way to directly control or communicate with the workers after they are daemonized.

I think the best you can do would be to start a separate worker with a small sleep_delay that only reads a specific queue, then use that queue for these jobs. A separate command is necessary because you can't start a worker pool where the workers have different sleep delays:

  1. Start your main worker: bin/delayed_job start
  2. Start your fast worker: bin/delayed_job start --sleep-delay=5 --queue=fast --identifier=999 (the identifier is necessary to differentiate the workers daemons)
  3. Update your job to use that queue:
class MyJob < ApplicationJob
  queue_as :fast

  def perform...
end

Notes:

  • When you want to stop the workers you'll also have to do it separately: bin/delayed_job stop and bin/delayed_job stop --identifier=999.

  • This introduces some potential parallelism and extra load on the server when both workers are working at the same time.

  • The main worker will process jobs from the fast queue too, it's just a matter of which worker grabs the job first. If you don't want that you need to setup the main worker to only read from the other queue(s), by default that's only 'default', so: bin/delayed_job start --queue=default.

huangapple
  • 本文由 发表于 2023年2月8日 09:38:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75380613.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定