У меня есть еще немного кода, чем это, поэтому я обрезаю его до того, что кажется уместным. За документированной, например, у меня есть класс питона для ZeroRPC использовать:Исключения для сервера peroon 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()
Сценарий питон порождены как ChildProcess от моего сервера Node.js, который прослушивает на стандартный вывод и стандартный поток ошибок. Когда время соединения клиента заканчивается или сервер выключается, я вызываю kill() в ChildProcess, который отправляет ему SIGTERM.
С помощью только что приведенного выше кода, «zpc stopped» никогда не попадает в обратный вызов Node.js, что указывает на то, что сервер ZeroRPC будет убит где-то в своем запуске. Кроме того, файл сокета все еще существует, показывая, что сервер также не закрывает сокет. Поэтому я полагал, что я бы назвал остановку() или близко() на сервере после захвата SIGTERM:
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
Изменение остановки() для закрытия() приводит к тому же самому окончательному набору исключений. Внедряя ту же идею в Javascript (Node.js), close() очищает запущенный сервер (и его файл сокета в каталоге), не выдавая никаких исключений или предупреждений.
Все это оставляет мне вопрос: как очистить сервер ZeroRPC в Python, если не остановить() или закрыть()?
Потрясающе, что работал отлично. Я пошел вперед и бросил zpc.close() после zpc.run(), чтобы убедиться, что сокет также очищается от системы. Благодаря! – Thomas
Вам не нужно добавлять .close() после .run()! Когда .run() возвращается, сервер zerorpc корректно и чисто остановлен. См. Более подробное объяснение здесь: http://stackoverflow.com/questions/19208535/how-to-run-zerorpc-as-a-greenlet – bombela
Чтобы уточнить, что я имею в виду под «очищенным» - это unix-сокет, который остается в путь, если я остановлю только() сервер. Вызов метода close() удаляет этот артефакт. – Thomas