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

Andrew Svetlov andrew.svetlov at gmail.com
Mon Oct 29 20:32:41 CET 2012


On Mon, Oct 29, 2012 at 9:10 PM, Yury Selivanov <yselivanov.ml at gmail.com> wrote:
> 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

Well, will take a look. I used zmq poll only.
It works for reading only, not for writing, right?
As I know you use proactor pattern.
Can reactor has some problems with this approach?
May embedded 0MQ poll be more effective via some internal optimizations?

>
> 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)
>



-- 
Thanks,
Andrew Svetlov



More information about the Python-ideas mailing list