32
32
33
33
34
34
import gevent_zmq as zmq
35
+ from .exceptions import TimeoutExpired
35
36
from .context import Context
37
+ from .channel_base import ChannelBase
36
38
37
39
38
40
class Sender (object ):
@@ -64,8 +66,11 @@ def _sender(self):
64
66
if not running :
65
67
return
66
68
67
- def __call__ (self , parts ):
68
- self ._send_queue .put (parts )
69
+ def __call__ (self , parts , timeout = None ):
70
+ try :
71
+ self ._send_queue .put (parts , timeout = timeout )
72
+ except gevent .queue .Full :
73
+ raise TimeoutExpired (timeout )
69
74
70
75
71
76
class Receiver (object ):
@@ -101,24 +106,25 @@ def _recver(self):
101
106
break
102
107
self ._recv_queue .put (parts )
103
108
104
- def __call__ (self ):
105
- return self ._recv_queue .get ()
109
+ def __call__ (self , timeout = None ):
110
+ try :
111
+ return self ._recv_queue .get (timeout = timeout )
112
+ except gevent .queue .Empty :
113
+ raise TimeoutExpired (timeout )
106
114
107
115
108
116
class Event (object ):
109
117
110
- __slots__ = ['_name' , '_args' , '_header' ]
118
+ __slots__ = ['_name' , '_args' , '_header' , '_identity' ]
111
119
112
120
def __init__ (self , name , args , context , header = None ):
113
121
self ._name = name
114
122
self ._args = args
115
123
if header is None :
116
- self ._header = {
117
- 'message_id' : context .new_msgid (),
118
- 'v' : 3
119
- }
124
+ self ._header = {'message_id' : context .new_msgid (), 'v' : 3 }
120
125
else :
121
126
self ._header = header
127
+ self ._identity = None
122
128
123
129
@property
124
130
def header (self ):
@@ -136,6 +142,14 @@ def name(self, v):
136
142
def args (self ):
137
143
return self ._args
138
144
145
+ @property
146
+ def identity (self ):
147
+ return self ._identity
148
+
149
+ @identity .setter
150
+ def identity (self , v ):
151
+ self ._identity = v
152
+
139
153
def pack (self ):
140
154
return msgpack .Packer ().pack ((self ._header , self ._name , self ._args ))
141
155
@@ -164,27 +178,38 @@ def __str__(self, ignore_args=False):
164
178
args = self ._args
165
179
try :
166
180
args = '<<{0}>>' .format (str (self .unpack (self ._args )))
167
- except :
181
+ except Exception :
168
182
pass
169
- return '{0} {1} {2}' .format (self ._name , self ._header ,
170
- args )
183
+ if self ._identity :
184
+ identity = ', ' .join (repr (x ) for x in self ._identity )
185
+ return '<{0}> {1} {2} {3}' .format (identity , self ._name ,
186
+ self ._header , args )
187
+ return '{0} {1} {2}' .format (self ._name , self ._header , args )
171
188
172
189
173
- class Events (object ):
190
+ class Events (ChannelBase ):
174
191
def __init__ (self , zmq_socket_type , context = None ):
175
192
self ._zmq_socket_type = zmq_socket_type
176
193
self ._context = context or Context .get_instance ()
177
- self ._socket = zmq .Socket (self ._context , zmq_socket_type )
178
- self ._send = self ._socket .send_multipart
179
- self ._recv = self ._socket .recv_multipart
180
- if zmq_socket_type in (zmq .PUSH , zmq .PUB , zmq .DEALER , zmq .ROUTER ):
194
+ self ._socket = self ._context .socket (zmq_socket_type )
195
+
196
+ if zmq_socket_type in (zmq .PUSH , zmq .PUB , zmq .DEALER , zmq .ROUTER , zmq .REQ ):
181
197
self ._send = Sender (self ._socket )
182
- if zmq_socket_type in (zmq .PULL , zmq .SUB , zmq .DEALER , zmq .ROUTER ):
198
+ else :
199
+ self ._send = None
200
+
201
+ if zmq_socket_type in (zmq .PULL , zmq .SUB , zmq .DEALER , zmq .ROUTER , zmq .REP ):
183
202
self ._recv = Receiver (self ._socket )
203
+ else :
204
+ self ._recv = None
184
205
185
206
@property
186
- def recv_is_available (self ):
187
- return self ._zmq_socket_type in (zmq .PULL , zmq .SUB , zmq .DEALER , zmq .ROUTER )
207
+ def recv_is_supported (self ):
208
+ return self ._recv is not None
209
+
210
+ @property
211
+ def emit_is_supported (self ):
212
+ return self ._send is not None
188
213
189
214
def __del__ (self ):
190
215
try :
@@ -226,42 +251,35 @@ def bind(self, endpoint, resolve=True):
226
251
r .append (self ._socket .bind (endpoint_ ))
227
252
return r
228
253
229
- def create_event (self , name , args , xheader = None ):
230
- xheader = {} if xheader is None else xheader
254
+ def new_event (self , name , args , xheader = None ):
231
255
event = Event (name , args , context = self ._context )
232
- for k , v in xheader .items ():
233
- if k == 'zmqid' :
234
- continue
235
- event .header [k ] = v
256
+ if xheader :
257
+ event .header .update (xheader )
236
258
return event
237
259
238
- def emit_event (self , event , identity = None ):
239
- if identity is not None :
240
- parts = list (identity )
260
+ def emit_event (self , event , timeout = None ):
261
+ if event . identity :
262
+ parts = list (event . identity or list () )
241
263
parts .extend (['' , event .pack ()])
242
264
elif self ._zmq_socket_type in (zmq .DEALER , zmq .ROUTER ):
243
265
parts = ('' , event .pack ())
244
266
else :
245
267
parts = (event .pack (),)
246
- self ._send (parts )
247
-
248
- def emit (self , name , args , xheader = None ):
249
- xheader = {} if xheader is None else xheader
250
- event = self .create_event (name , args , xheader )
251
- identity = xheader .get ('zmqid' , None )
252
- return self .emit_event (event , identity )
268
+ self ._send (parts , timeout )
253
269
254
- def recv (self ):
255
- parts = self ._recv ()
256
- if len (parts ) == 1 :
257
- identity = None
258
- blob = parts [0 ]
259
- else :
270
+ def recv (self , timeout = None ):
271
+ parts = self ._recv (timeout = timeout )
272
+ if len (parts ) > 2 :
260
273
identity = parts [0 :- 2 ]
261
274
blob = parts [- 1 ]
275
+ elif len (parts ) == 2 :
276
+ identity = parts [0 :- 1 ]
277
+ blob = parts [- 1 ]
278
+ else :
279
+ identity = None
280
+ blob = parts [0 ]
262
281
event = Event .unpack (blob )
263
- if identity is not None :
264
- event .header ['zmqid' ] = identity
282
+ event .identity = identity
265
283
return event
266
284
267
285
def setsockopt (self , * args ):
0 commit comments