如何正确地动态关闭PythonRQ工作进程?
使用,我们试图动态管理工作进程。我们使用定制的辅助脚本,其(简化形式)如下所示:如何正确地动态关闭PythonRQ工作进程?,python,asynchronous,process,signals,Python,Asynchronous,Process,Signals,使用,我们试图动态管理工作进程。我们使用定制的辅助脚本,其(简化形式)如下所示: 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() 我们对关闭工人特别感兴趣。我们主要关心的
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()
我们对关闭工人特别感兴趣。我们主要关心的是如何优雅地关闭一个工人,使当前的工作能够在关闭之前完成。相应的Worker
对象上的request\u stop(…)
信号处理程序似乎执行了我们需要的操作,但似乎没有办法(至少据我所知)发出它,除非通过在终端中运行的Worker进程上按CTRL+C
在我看来,有两种可能的解决方案(肯定会有更多)——按优先顺序排列:
rq
库,将信号发送到request\u stop
,从而触发正常关机Fabric
运行远程命令或类似的内容)如果有更好的方法来解决这个问题,或者有不同的替代方案来实现相同的目标,我将非常感谢您的建议。选项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
在主脚本中,按照@Borys的建议获取worker PID,发送热停止请求,然后取消链接(“path/to/worker\u NAME.%d”%worker\u PID),以确保正常关闭:)
但这只适用于运行无限循环的工人。如果工作进程调用的东西甚至会阻塞普通的顺序一次性作业,那么您必须进一步跟踪可能的阻塞例程以从那里解决,例如应用某种超时策略。如果您需要PID,实际上可以从w.PID获取它