尝试停止或clos时出现ZeroRPC python服务器异常

2024-09-26 18:16:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我的代码比这多了一点,所以我把它删减到似乎相关的地方。根据文档中的示例,我有一个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服务器,该如何干净地停止呢?在


Tags: inpyself服务器packagesusrlinesite
1条回答
网友
1楼 · 发布于 2024-09-26 18:16:41

使用gevent.信号()设置信号处理程序而不是信号。信号(). 在

这是因为标准模块signal直接映射unixapi,后者在gevent eventloop之外运行信号处理程序,而没有任何gevent greenlet/coroutine的概念。gevent.信号与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()

相关问题 更多 >

    热门问题