[Python-ideas] Async API: some code to review

Yury Selivanov yselivanov.ml at gmail.com
Mon Oct 29 20:10:17 CET 2012


On 2012-10-29, at 2:02 PM, Andrew Svetlov <andrew.svetlov at gmail.com> wrote:

> Pollster has to support any object as file descriptor.
> The use case is ZeroMQ sockets: they are implemented at user level and
> socket is just some opaque structure wrapped by Python object.
> ZeroMQ has own poll function to process zmq sockets as well as regular
> sockets/pipes/files.

Well, you can use epoll/select/kqueue or whatever else with ZMQ sockets.
Just get the underlying file descriptor with 'getsockopt', as described
here: http://api.zeromq.org/master:zmq-getsockopt#toc20

For instance, here is a stripped out zmq support classes I have in my
framework:

  class Socket(_zmq_Socket):
      def __init__(self, *args, **kwargs):
          super().__init__(*args, **kwargs)
          self.fileno = self.getsockopt(FD)

      ...
 
      #coroutine 
      def send(self, data, *, flags=0, copy=True, track=False):
          flags |= NOBLOCK

          try:
              result = _zmq_Socket.send(self, data, flags, copy, track)
          except ZMQError as e:
              if e.errno != EAGAIN:
                  raise
              self._sending = (Promise(), data, flags, copy, track)
              self._scheduler.proactor._schedule_write(self)
              return self._sending[0]
          else:
              p = Promise()
              p.send(result)
              return p
      ...

  class Context(_zmq_Context):
      _socket_class = Socket

And '_schedule_write' accepts any object with 'fileno' property, and
uses an appropriate polling mechanism to poll.

So to use a non-blocking ZMQ sockets, you simply do:

    context = Context()
    socket = context.socket(zmq.REP)
    ...
    yield socket.send(message)




More information about the Python-ideas mailing list