如何优雅地关闭 python thrift 服务器 TProcessPoolServer?我没有找到任何文档、示例或博客文章。以下是我迄今为止的经历。
我直接在命令行 ./thrift_service.py 上运行我的 thrift 服务器,而不是在主管之下。我正在使用 python 2.6 和 thrift 0.8.0。
我最初尝试过:
server = TProcessPoolServer(processor, transport, tfactory, pfactory)
try:
server.serve()
finally:
server.stop()
当我向父 python 进程发送 sigterm 时,我在输出中看到“终止”,该进程被终止,但它的子进程是孤立的并继续运行。
然后我偶然发现了thrift server tests,并尝试了:
import signal
def set_alarm(server):
def clean_shutdown(signum, frame):
for worker in server.workers:
logging.error("Terminating worker: {0}".format(worker))
worker.terminate()
logging.error("Requesting server to stop()")
try:
server.stop()
except (KeyboardInterrupt, SystemExit):
pass
except Exception as err:
logging.exception(err)
def logme(s, *args, **kwargs):
logging.error(">>> {0} <<<".format(s))
clean_shutdown(*args, **kwargs)
signal.signal(signal.SIGALRM, clean_shutdown)
signal.signal(signal.SIGHUP, clean_shutdown)
signal.signal(signal.SIGINT, clean_shutdown)
signal.signal(signal.SIGTERM, lambda x, y: logme("SIGTERM", x, y))
server = TProcessPoolServer(processor, transport, tfactory, pfactory)
set_alarm(server)
server.serve()
当我向父 python 进程发送 sigterm、sigalrm、sighup 或 sigint 时,服务器停止接受连接,但进程没有终止。
在输出中我看到:
ERROR:root:>>> SIGTERM <<<
ERROR:root:Terminating worker: <Process(Process-1, started daemon)>
ERROR:root:Terminating worker: <Process(Process-2, started daemon)>
ERROR:root:Terminating worker: <Process(Process-3, started daemon)>
ERROR:root:Terminating worker: <Process(Process-4, started daemon)>
ERROR:root:Terminating worker: <Process(Process-5, started daemon)>
ERROR:root:Requesting server to stop()
这是意料之中的,但是随后再次捕获到信号,进程不再处于启动状态,并且要求服务器停止。这部分发生了大约十次,然后就没有更多的输出了。
ERROR:root:>>> SIGTERM <<<
ERROR:root:Terminating worker: <Process(Process-1, unknown daemon)>
ERROR:root:Requesting server to stop()
有时,我会在多处理库中看到一个 AssertionError:
Traceback (most recent call last):
File "/path/to/thrift_service.py", line 340, in clean_shutdown
server.stop()
File "/usr/local/lib/python2.6/dist-packages/thrift/server/TProcessPoolServer.py", line 123, in stop
self.stopCondition.notify()
File "/usr/lib/python2.6/multiprocessing/synchronize.py", line 223, in notify
assert not self._wait_semaphore.acquire(False)
AssertionError