Search code examples
pythonasynchronouszeromqpyzmq

How can I receive a ZeroMQ (pyzmq) JSON message asynchronously?


Right now I have the following structure in my code. The request is directly parsed as JSON.

while True:
   if self.rest_sock.poll(timeout=0):
      request = self.rest_sock.recv_json()
      ...

I want to replace the loop with an asynchronous call of a function (to reduce CPU time as explained here: https://stackoverflow.com/a/21937311/10555800). This is done by registering a function as an event handler by using on_recv(). But the JSON message is not parsed. I assume I could parse it myself as explained e.g. here https://stackoverflow.com/a/34242555/10555800. But I was wondering why there nothing equivalent to socket.recv_json() for an async receive of json messages like on_recv_json().

Edit (Answering Questions from @bazza):

  • There is something else for my program to do in the meantime. This did lead to some other issues and I have already fixed this by setting the timeout to None.
  • I assume I could also remove the poll as you suggested as everything related to the socket connection is running in its own thread and therefore should not block the complete program

Solution

  • What else is going on in the code?

    • You only poll with a timeout of 0 if there's something else for the program to do when there are no inbound messages available. When the poll returns indicating no socket is ready, have the program go do that something else
    • You poll several sockets (see here) with a non-zero timeout if you need to react to whichever of several sockets becomes ready to read, and have nothing to do in the meantime.
    • If you have only one socket, and you're simply waiting for a message to arrive before doing anything else, simply call recv(), which will block until a message turns up. Polling in that case is not necessary.

    It's helpful to know a dictionary definition of "poll" as meaning "check on the status of".