mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-01 15:42:55 +08:00
100 lines
2.8 KiB
Python
100 lines
2.8 KiB
Python
"""
|
|
This is somewhat legally ambigious, since it technically
|
|
hasn't been merged in gevent_zeromq but given that the
|
|
author issued it as a Pull Request on a MIT project,
|
|
indicates that its probably fine to use. ~Steve
|
|
"""
|
|
|
|
import zmq
|
|
from zmq import *
|
|
|
|
from zmq.core.poll import Poller as _original_Poller
|
|
|
|
import gevent
|
|
from gevent import select
|
|
from gevent_zeromq.core import _Socket
|
|
|
|
def patch_poller(self):
|
|
zmq.Poller = _Poller
|
|
|
|
class _Poller(_original_Poller):
|
|
"""
|
|
Replacement for :class:`zmq.core.Poller`
|
|
|
|
Ensures that the greened Poller below is used in calls
|
|
to :meth:`zmq.core.Poller.poll`.
|
|
"""
|
|
|
|
def _get_descriptors(self):
|
|
"""
|
|
Returns three elements tuple with socket descriptors ready for
|
|
gevent.select
|
|
"""
|
|
rlist = []
|
|
wlist = []
|
|
xlist = []
|
|
|
|
for socket, flags in self.sockets.items():
|
|
if isinstance(socket, _Socket):
|
|
fd = socket.getsockopt(FD)
|
|
elif isinstance(socket, int):
|
|
fd = socket
|
|
elif hasattr(socket, 'fileno'):
|
|
try:
|
|
fd = int(socket.fileno())
|
|
except:
|
|
raise ValueError('fileno() must return an valid integer fd')
|
|
else:
|
|
raise TypeError("Socket must be a 0MQ socket, an integer fd or \
|
|
have a fileno() method: %r" % socket)
|
|
|
|
if flags & POLLIN: rlist.append(fd)
|
|
if flags & POLLOUT: wlist.append(fd)
|
|
if flags & POLLERR: xlist.append(fd)
|
|
|
|
return (rlist, wlist, xlist)
|
|
|
|
def poll(self, timeout=-1):
|
|
"""Overridden method to ensure that the green version of Poller is used
|
|
|
|
Behaves the same as :meth:`zmq.core.Poller.poll`
|
|
"""
|
|
|
|
if timeout is None:
|
|
timeout = -1
|
|
|
|
timeout = int(timeout)
|
|
if timeout < 0:
|
|
timeout = -1
|
|
|
|
rlist = None
|
|
wlist = None
|
|
xlist = None
|
|
|
|
if timeout > 0:
|
|
tout = gevent.Timeout.start_new(timeout/1000.0)
|
|
|
|
try:
|
|
# Loop until timeout or events available
|
|
while True:
|
|
events = super(_Poller, self).poll(0)
|
|
if events or timeout == 0:
|
|
return events
|
|
|
|
# wait for activity on sockets in a green way
|
|
if not rlist and not wlist and not xlist:
|
|
rlist, wlist, xlist = self._get_descriptors()
|
|
|
|
try:
|
|
select.select(rlist, wlist, xlist)
|
|
except gevent.select.error, ex:
|
|
raise ZMQError(*ex.args)
|
|
|
|
except gevent.Timeout, t:
|
|
if t is not tout:
|
|
raise
|
|
return []
|
|
finally:
|
|
if timeout > 0:
|
|
tout.cancel()
|