gpt4 book ai didi

javascript - 尝试停止或关闭时 ZeroRPC python 服务器异常

转载 作者:搜寻专家 更新时间:2023-11-01 00:18:34 24 4
gpt4 key购买 nike

我的代码比这多得多,所以我将其精简到看起来相关的部分。根据记录的示例,我有一个供 ZeroRPC 使用的 python 类:

import zerorpc, sys, signal

class MyClass:
pass

zpc = 0
if __name == '__main__':
zpc = zerorpc.Server(MyClass)
zpc.bind('ipc://./mysocket.sock')
zpc.run()
print("zpc stopped"); sys.stdout.flush()

python 脚本作为 ChildProcess 从我的 Node.js 服务器生成,该服务器监听 stdout 和 stderr。当客户端连接超时或服务器关闭时,我在 ChildProcess 上调用 kill() ,它向它发送 SIGTERM。

只有上面的代码,'zpc stopped' 永远不会在 Node.js 回调中被捕获,这向我表明 ZeroRPC 服务器在其运行循环的某个地方被杀死。此外,套接字文件仍然存在,表明服务器也没有关闭套接字。所以我想我会在捕获 SIGTERM 后在服务器上调用 stop() 或 close():

def sig_handle (signal, frame):
global zpc
print("SIGTERM received.") # <-- this does occur
zpc.stop() # <-- Exception thrown here and at run()
sys.exit(0)

signal.signal(signal.SIGTERM, sig_handle)

异常由 Node.js 通过其 stderr 回调获取:

Gateway Error:   File "/usr/lib/python2.6/site-packages/zerorpc/core.py", line 178, in stop

Gateway Error: self._acceptor_task.kill()
File "/usr/lib64/python2.6/site-packages/gevent/greenlet.py", line 235, in kill

Gateway Error: waiter.get()
File "/usr/lib64/python2.6/site-packages/gevent/hub.py", line 568, in get

Gateway Error: return self.hub.switch()
File "/usr/lib64/python2.6/site-packages/gevent/hub.py", line 330, in switch
switch_out()
File "/usr/lib64/python2.6/site-packages/gevent/hub.py", line 334, in switch_out
raise AssertionError('Impossible to call blocking function in the event loop callback')
AssertionError: Impossible to call blocking function in the event loop callback

Gateway Error: Traceback (most recent call last):
File "gateway.py", line 111, in <module>
zpc.run()

Gateway Error: File "/usr/lib/python2.6/site-packages/zerorpc/core.py", line 171, in run
self._acceptor_task.get()
File "/usr/lib64/python2.6/site-packages/gevent/greenlet.py", line 258, in get

Gateway Error: result = self.parent.switch()
File "/usr/lib64/python2.6/site-packages/gevent/hub.py", line 331, in switch

Gateway Error: return greenlet.switch(self)
AssertionError: Impossible to call blocking function in the event loop callback

将 stop() 更改为 close() 会导致相同的最终异常集。在 Javascript (Node.js) 中实现相同的想法,close() 清理正在运行的服务器(及其目录中的套接字文件)而不会抛出任何异常或警告。

这一切都给我留下了一个问题:如果不是通过 stop() 或 close(),如何在 Python 中干净地停止 ZeroRPC 服务器?

最佳答案

使用 gevent.signal() 代替 signal.signal() 来设置信号处理程序。

这是因为标准模块信号直接映射了 UNIX API,它在 gevent eventloop 之外运行信号处理程序,没有任何 gevent greenlet/coroutine 的概念。 gevent.signal 与 gevent ioloop 集成,并确保在 eventloop 中它自己的 greenlet 中执行信号处理程序。

Gevent 兼容解决方案:

import zerorpc, sys, gevent, signal, os

class MyClass:
pass

if __name__ == '__main__':
zpc = zerorpc.Server(MyClass)
zpc.bind('ipc://./mysocket.sock')
gevent.signal(signal.SIGTERM, zpc.stop)
zpc.run()
print("zpc stopped"); sys.stdout.flush()

关于javascript - 尝试停止或关闭时 ZeroRPC python 服务器异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21140384/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com