Tho*_*mas 2 javascript python zeromq node.js greenlets
我有比这更多的代码,所以我把它修改为看似相关的东西.根据记录的示例,我有一个用于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()
Run Code Online (Sandbox Code Playgroud)
python脚本从我的Node.js服务器生成为ChildProcess,它监听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)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
将stop()更改为close()会导致相同的最终异常集.在Javascript(Node.js)中实现相同的想法,close()清除正在运行的服务器(及其在目录中的套接字文件),而不会抛出任何异常或警告.
这一切都让我有了一个问题:如果不是通过stop()或close(),如何在Python中干净地停止ZeroRPC服务器?
小智 6
使用gevent.signal()设置信号处理程序而不是signal.signal().
这是因为标准模块信号直接映射UNIX API,它运行gevent eventloop之外的信号处理程序,没有任何gevent greenlet/coroutine的概念.gevent.signal与gevent ioloop集成,并确保在事件循环中在自己的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()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1361 次 |
| 最近记录: |