我的代码比这多了一点,所以我把它删减到似乎相关的地方。根据文档中的示例,我有一个python类供ZeroRPC使用:
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从节点.js监听stdout和stderr的服务器。当客户机连接超时或服务器关闭时,我对向其发送SIGTERM的ChildProcess调用kill()。在
只有上面的代码,“zpc stopped”永远不会在节点.js回调,它指示ZeroRPC服务器在其运行循环的某个地方被杀死。另外,套接字文件仍然存在,表明服务器也没有关闭套接字。所以我想在捕获SIGTERM后在服务器上调用stop()或close():
^{pr2}$例外情况由节点.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中实现相同的思想(节点.js),close()清理正在运行的服务器(及其目录中的套接字文件),而不会引发任何异常或警告。在
这一切都给我留下了一个问题:如果不是通过stop()或close()来停止Python中的ZeroRPC服务器,该如何干净地停止呢?在
使用gevent.信号()设置信号处理程序而不是信号。信号(). 在
这是因为标准模块signal直接映射unixapi,后者在gevent eventloop之外运行信号处理程序,而没有任何gevent greenlet/coroutine的概念。gevent.信号与gevent ioloop集成,并确保在eventloop中以自己的greenlet执行信号处理程序。在
Gevent兼容解决方案:
相关问题 更多 >
编程相关推荐