How to resolve the Tornado + ZMQ error

Like everyone else, I work through PoC chat using Tornado (SockJS-Tornado) + pyzmq.

The general idea is to have instances of N tornadoes, each with associated websocket clients, exchanging messages through a ZMQ device. In other words, the websocket client in instance A is published to the ZMQ Forwarder. Instances B and C have handlers that are subscribed to the Forwarder so that the corresponding topics are passed to websocket clients B and C. And yes, clients in B and C also have publisher sockets that are published to the Forwarder.

Everything works fine, but my problem is that if one of the connected clients disconnects unexpectedly (for example, closes or refreshes the browser tab), I get streams of errors like this:

ERROR:tornado.application:Exception in callback None
Traceback (most recent call last):
  File ".../tornado/ioloop.py", line 836, in start
  fd_obj, handler_func = self._handlers[fd]
KeyError: 246850817
ERROR:tornado.application:Exception in callback None
Traceback (most recent call last):
  File ".../tornado/ioloop.py", line 836, in start
  fd_obj, handler_func = self._handlers[fd]
KeyError: 246850817

      

So, there is one Context at the application level, but each handler instantiated gets its own Publisher and Subscriber sockets. Subscriber sockets use ZMQStream, for example:

   def _set_up_sockets(self):
    self.publisher = self.context.socket(zmq.PUB)
    self.publisher.connect('tcp://127.0.0.1:5559')
    self.subscriber = self.context.socket(zmq.SUB)
    self.subscriber.connect('tcp://127.0.0.1:5560')
    self.subscriber.setsockopt(zmq.SUBSCRIBE, "_NOROOM_")
    stream = zmqstream.ZMQStream(self.subscriber,
                                 io_loop=self.session.server.io_loop)
    stream.on_recv(self.echo)

      

The ioloop passed to ZMQStream is the global io_loop created when the application starts:

ioloop.install()
io_loop = IOLoop.instance()

      

It is actually an instance of the ZMQ subclass of Tornado IOLoop. Any idea what is causing this error? I have cleanup methods, on_connection_close

and on_close

, but they don't seem to be called at any point.

Oh, this is Python 2.7.8, ZeroMQ 4.0.4, PyZMQ 14.4.0 (same thing happened with 14.3.1).

Thank you in advance

+3


source to share


1 answer


Make sure you are calling _set_up_sockets inside the main thread.



Since you only have one IOLoop, the zmq FAQ clearly states that you need to create and use sockets on the same thread.

0


source







All Articles