On Mon, Oct 29, 2012 at 9:10 PM, Yury Selivanov <yselivanov.ml@gmail.com> wrote:
On 2012-10-29, at 2:02 PM, Andrew Svetlov <andrew.svetlov@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