Javascript 尝试停止或关闭时出现ZeroRPC python服务器异常

Javascript 尝试停止或关闭时出现ZeroRPC python服务器异常,javascript,python,node.js,zeromq,greenlets,Javascript,Python,Node.js,Zeromq,Greenlets,我有比这更多的代码,所以我将把它缩减到似乎相关的部分。根据记录的示例,我有一个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 sto

我有比这更多的代码,所以我将把它缩减到似乎相关的部分。根据记录的示例,我有一个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脚本是从my Node.js服务器生成的一个子进程,该服务器侦听stdout和stderr。当客户端连接超时或服务器关闭时,我在向其发送SIGTERM的ChildProcess上调用kill()

只有上面的代码,“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)
def sig_手柄(信号,帧):
全球zpc
打印(“SIGTERM received.”#使用gevent.signal()来设置信号处理程序,而不是signal.signal()

这是因为标准模块信号直接映射UNIX API,该API在gevent eventloop之外运行信号处理程序,而没有任何gevent greenlet/Corroutine概念。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()

太棒了,效果很好。我继续在zpc.run()之后抛出zpc.close(),以确保套接字也从系统中清除。谢谢您不需要在.run()之后添加.close()!当.run()返回时,zerorpc服务器将正确、干净地停止。这里有一个更详细的解释:为了澄清我所说的“清理掉”是什么意思,如果我只停止()服务器,路径中会保留unix套接字。调用close()将删除该工件。
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()