title: ZeroRPC python server exceptions when attempting to stop or close
body: <p>I have quite a bit more code than this so I'm trimming it down to just what seems to be relevant.  Per the documented example, I have a python class for ZeroRPC to use:</p>
  
  <pre><code>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()
  </code></pre>
  
  <p>The python script is spawned as a ChildProcess from my Node.js server which listens to stdout and stderr.  When the client connection times out, or the server shuts down, I call kill() on the ChildProcess which sends SIGTERM to it.  </p>
  
  <p>With just the code above, the 'zpc stopped' never gets captured at the Node.js callback which indicates to me that the ZeroRPC server gets killed somewhere in its run-loop.  Also, the socket file still exists indicating the server doesn't close the socket, either.  So I figured I would call stop() or close() on the server after capturing SIGTERM:</p>
  
  <pre><code>def sig_handle (signal, frame):
      global zpc
      print("SIGTERM received.") # &lt;-- this does occur
      zpc.stop() # &lt;-- Exception thrown here and at run()
      sys.exit(0)
  
  signal.signal(signal.SIGTERM, sig_handle)
  </code></pre>
  
  <p>The exceptions are picked up by Node.js through its stderr callback:</p>
  
  <pre><code>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 &lt;module&gt;
      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
  </code></pre>
  
  <p>Changing stop() to close() results in the same ultimate set of exceptions.  Implementing the same idea in Javascript (Node.js), close() cleans up a running server (and its socket file in the directory) without throwing any exceptions or warnings.  </p>
  
  <p>This all leaves me with the question: how does one cleanly stop a ZeroRPC server in Python if not by stop() or close()?</p>