Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9736cbf

Browse files
committed
Refactoring
1 parent 6502e96 commit 9736cbf

File tree

8 files changed

+987
-938
lines changed

8 files changed

+987
-938
lines changed

zerorpc/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,9 @@
66
__license__ = 'MIT'
77
__copyright__ = 'Copyright 2012 dotCloud, Inc.'
88

9-
from gevent_zerorpc import *
9+
from .exceptions import *
10+
from .context import *
11+
from .socket import *
12+
from .channel import *
13+
from .events import *
14+
from .core import *

zerorpc/channel.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import sys
4+
5+
import gevent.pool
6+
import gevent.queue
7+
import gevent.event
8+
import gevent.local
9+
import gevent.coros
10+
11+
from .exceptions import TimeoutExpired
12+
13+
14+
class ChannelMultiplexer(object):
15+
def __init__(self, events, ignore_broadcast=False):
16+
self._events = events
17+
self._active_channels = {}
18+
self._channel_dispatcher_task = None
19+
self._broadcast_queue = None
20+
if events.recv_is_available and not ignore_broadcast:
21+
self._broadcast_queue = gevent.queue.Queue(maxsize=1)
22+
self._channel_dispatcher_task = gevent.spawn(
23+
self._channel_dispatcher)
24+
25+
@property
26+
def recv_is_available(self):
27+
return self._events.recv_is_available
28+
29+
def __del__(self):
30+
self.close()
31+
32+
def close(self):
33+
if self._channel_dispatcher_task:
34+
self._channel_dispatcher_task.kill()
35+
36+
def create_event(self, name, args, xheader={}):
37+
return self._events.create_event(name, args, xheader)
38+
39+
def emit_event(self, event, identity=None):
40+
return self._events.emit_event(event, identity)
41+
42+
def emit(self, name, args, xheader={}):
43+
return self._events.emit(name, args, xheader)
44+
45+
def recv(self):
46+
if self._broadcast_queue is not None:
47+
event = self._broadcast_queue.get()
48+
else:
49+
event = self._events.recv()
50+
return event
51+
52+
def _channel_dispatcher(self):
53+
while True:
54+
event = self._events.recv()
55+
channel_id = event.header.get('response_to', None)
56+
57+
queue = None
58+
if channel_id is not None:
59+
channel = self._active_channels.get(channel_id, None)
60+
if channel is not None:
61+
queue = channel._queue
62+
elif self._broadcast_queue is not None:
63+
queue = self._broadcast_queue
64+
65+
if queue is None:
66+
print >> sys.stderr, \
67+
'zerorpc.ChannelMultiplexer, ', \
68+
'unable to route event:', \
69+
event.__str__(ignore_args=True)
70+
else:
71+
queue.put(event)
72+
73+
def channel(self, from_event=None):
74+
if self._channel_dispatcher_task is None:
75+
self._channel_dispatcher_task = gevent.spawn(
76+
self._channel_dispatcher)
77+
return Channel(self, from_event)
78+
79+
@property
80+
def active_channels(self):
81+
return self._active_channels
82+
83+
84+
class Channel(object):
85+
86+
def __init__(self, multiplexer, from_event=None):
87+
self._multiplexer = multiplexer
88+
self._channel_id = None
89+
self._zmqid = None
90+
self._queue = gevent.queue.Queue(maxsize=1)
91+
if from_event is not None:
92+
self._channel_id = from_event.header['message_id']
93+
self._zmqid = from_event.header.get('zmqid', None)
94+
self._multiplexer._active_channels[self._channel_id] = self
95+
self._queue.put(from_event)
96+
97+
@property
98+
def recv_is_available(self):
99+
return self._multiplexer.recv_is_available
100+
101+
def __del__(self):
102+
self.close()
103+
104+
def close(self):
105+
if self._channel_id is not None:
106+
del self._multiplexer._active_channels[self._channel_id]
107+
self._channel_id = None
108+
109+
def emit(self, name, args, xheader={}):
110+
event = self._multiplexer.create_event(name, args, xheader)
111+
112+
if self._channel_id is None:
113+
self._channel_id = event.header['message_id']
114+
self._multiplexer._active_channels[self._channel_id] = self
115+
else:
116+
event.header['response_to'] = self._channel_id
117+
118+
# TODO debug middleware
119+
# print time.time(), 'channel emit', event
120+
self._multiplexer.emit_event(event, self._zmqid)
121+
122+
def recv(self, timeout=None):
123+
try:
124+
event = self._queue.get(timeout=timeout)
125+
except gevent.queue.Empty:
126+
raise TimeoutExpired(timeout)
127+
# TODO debug middleware
128+
# print time.time(), 'channel recv', event
129+
return event

zerorpc/context.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# -*- coding: utf-8 -*-
2+
3+
4+
import uuid
5+
6+
import gevent_zmq as zmq
7+
8+
9+
class Context(zmq.Context):
10+
_instance = None
11+
12+
def __init__(self):
13+
self._middlewares = []
14+
self._middlewares_hooks = {
15+
'resolve_endpoint': [],
16+
'raise_error': []
17+
}
18+
19+
@staticmethod
20+
def get_instance():
21+
if Context._instance is None:
22+
Context._instance = Context()
23+
return Context._instance
24+
25+
def new_msgid(self):
26+
return str(uuid.uuid4())
27+
28+
def register_middleware(self, middleware_instance):
29+
registered_count = 0
30+
self._middlewares.append(middleware_instance)
31+
for hook in self._middlewares_hooks.keys():
32+
functor = getattr(middleware_instance, hook, None)
33+
if functor is None:
34+
try:
35+
functor = middleware_instance.get(hook, None)
36+
except AttributeError:
37+
pass
38+
if functor is not None:
39+
self._middlewares_hooks[hook].append(functor)
40+
registered_count += 1
41+
return registered_count
42+
43+
def middleware_resolve_endpoint(self, endpoint):
44+
for functor in self._middlewares_hooks['resolve_endpoint']:
45+
endpoint = functor(endpoint)
46+
return endpoint
47+
48+
def middleware_raise_error(self, event):
49+
for functor in self._middlewares_hooks['raise_error']:
50+
functor(event)

0 commit comments

Comments
 (0)