使用Python RQ,我们正在尝试动态管理工作进程。我们使用定制的工作脚本,(简化形式)如下:
from rq import Connection, Worker
queues_to_listen_on = get_queues_to_listen_on()
with Connection(connection = get_worker_connection()):
w = Worker(queues_to_listen_on)
w.work()
我们对工人的关闭特别感兴趣。我们主要关注的是如何正常关闭工作人员,以便在关闭之前完成当前工作。相应的request_stop(...)
对象上的Worker
信号处理程序似乎做了我们需要的事情,但似乎没有办法(至少据我所知)发出它,除非是通过按{{1}关于在终端中运行的工作进程。
正如我所看到的,有两种可能的解决方案(肯定会有更多) - 按优先顺序排列:
CTRL+C
库,将信号发送到rq
,从而触发正常关机。request_stop
来运行远程命令或其他东西线)。如果有更好的方法来解决这个问题,或者有另一种方法可以达到同样的目标,我将非常感谢您的建议。
答案 0 :(得分:4)
选项1在设计方面肯定更好。
但是,要解决您必须使用CTRL + C
退出流程的特定问题(我也讨厌这样做),您可以为您的员工使用以下策略:
# WORKER_NAME.py
import os
PID = os.getpid()
@atexit.register
def clean_shut():
print "Clean shut performed"
try:
os.unlink("WORKER_NAME.%d" % PID)
except:
pass
# Worker main
def main():
f = open("WORKER_NAME.%d" % PID, "w")
f.write("Delete this to end WORKER_NAME gracefully")
f.close()
while os.path.exists("WORKER_NAME.%d" % PID):
# Worker working
在你的主脚本中,获取工作者PID为@Borys建议,发送热停止请求,os.unlink("path/to/WORKER_NAME.%d" % worker_PID)
以确保正常关闭:)
这只适用于运行无限循环的工作人员。如果工作进程调用阻止普通顺序一次性作业的事情,则必须进一步跟踪可能阻塞的例程以从中解决,例如应用某种超时策略。