1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 from __future__ import absolute_import
21
22 import threading
23
24 from cproton import PN_CONNECTION_BOUND, PN_CONNECTION_FINAL, PN_CONNECTION_INIT, PN_CONNECTION_LOCAL_CLOSE, \
25 PN_CONNECTION_LOCAL_OPEN, PN_CONNECTION_REMOTE_CLOSE, PN_CONNECTION_REMOTE_OPEN, PN_CONNECTION_UNBOUND, PN_DELIVERY, \
26 PN_LINK_FINAL, PN_LINK_FLOW, PN_LINK_INIT, PN_LINK_LOCAL_CLOSE, PN_LINK_LOCAL_DETACH, PN_LINK_LOCAL_OPEN, \
27 PN_LINK_REMOTE_CLOSE, PN_LINK_REMOTE_DETACH, PN_LINK_REMOTE_OPEN, PN_PYREF, PN_SESSION_FINAL, PN_SESSION_INIT, \
28 PN_SESSION_LOCAL_CLOSE, PN_SESSION_LOCAL_OPEN, PN_SESSION_REMOTE_CLOSE, PN_SESSION_REMOTE_OPEN, PN_TIMER_TASK, \
29 PN_TRANSPORT, PN_TRANSPORT_CLOSED, PN_TRANSPORT_ERROR, PN_TRANSPORT_HEAD_CLOSED, PN_TRANSPORT_TAIL_CLOSED, \
30 pn_cast_pn_connection, pn_cast_pn_delivery, pn_cast_pn_link, pn_cast_pn_session, pn_cast_pn_transport, \
31 pn_class_name, pn_collector, pn_collector_free, pn_collector_more, pn_collector_peek, pn_collector_pop, \
32 pn_collector_put, pn_collector_release, pn_event_class, pn_event_connection, pn_event_context, pn_event_delivery, \
33 pn_event_link, pn_event_session, pn_event_transport, pn_event_type, pn_event_type_name, pn_py2void, pn_void2py
34
35 from ._delivery import Delivery
36 from ._endpoints import Connection, Link, Session
37 from ._transport import Transport
41
43 self._impl = pn_collector()
44
45 - def put(self, obj, etype):
46 pn_collector_put(self._impl, PN_PYREF, pn_py2void(obj), etype.number)
47
49 return Event.wrap(pn_collector_peek(self._impl))
50
52 return pn_collector_more(self._impl)
53
55 ev = self.peek()
56 pn_collector_pop(self._impl)
57
59 pn_collector_release(self._impl)
60
62 pn_collector_free(self._impl)
63 del self._impl
64
65
66 if "TypeExtender" not in globals():
70
72 try:
73 return self.number
74 finally:
75 self.number += 1
76
79 _lock = threading.Lock()
80 _extended = TypeExtender(10000)
81 TYPES = {}
82
83 - def __init__(self, name=None, number=None, method=None):
84 if name is None and number is None:
85 raise TypeError("extended events require a name")
86 try:
87 self._lock.acquire()
88 if name is None:
89 name = pn_event_type_name(number)
90
91 if number is None:
92 number = self._extended.next()
93
94 if method is None:
95 method = "on_%s" % name
96
97 self.name = name
98 self.number = number
99 self.method = method
100
101 self.TYPES[number] = self
102 finally:
103 self._lock.release()
104
106 return "EventType(name=%s, number=%d)" % (self.name, self.number)
107
110
118
121
124
125 @property
128
129 @property
132
133 - def dispatch(self, handler, type=None):
139
141 return "%s(%r)" % (self._type, self.context)
142
143
144 -def _core(number, method):
145 return EventType(number=number, method=method)
146
150
151
152 wrappers = {
153 "pn_void": lambda x: pn_void2py(x),
154 "pn_pyref": lambda x: pn_void2py(x),
155 "pn_connection": lambda x: Connection.wrap(pn_cast_pn_connection(x)),
156 "pn_session": lambda x: Session.wrap(pn_cast_pn_session(x)),
157 "pn_link": lambda x: Link.wrap(pn_cast_pn_link(x)),
158 "pn_delivery": lambda x: Delivery.wrap(pn_cast_pn_delivery(x)),
159 "pn_transport": lambda x: Transport.wrap(pn_cast_pn_transport(x))
160 }
161
162
163 -class Event(EventBase):
164 TIMER_TASK = _core(PN_TIMER_TASK, "on_timer_task")
165
166 CONNECTION_INIT = _core(PN_CONNECTION_INIT, "on_connection_init")
167 CONNECTION_BOUND = _core(PN_CONNECTION_BOUND, "on_connection_bound")
168 CONNECTION_UNBOUND = _core(PN_CONNECTION_UNBOUND, "on_connection_unbound")
169 CONNECTION_LOCAL_OPEN = _core(PN_CONNECTION_LOCAL_OPEN, "on_connection_local_open")
170 CONNECTION_LOCAL_CLOSE = _core(PN_CONNECTION_LOCAL_CLOSE, "on_connection_local_close")
171 CONNECTION_REMOTE_OPEN = _core(PN_CONNECTION_REMOTE_OPEN, "on_connection_remote_open")
172 CONNECTION_REMOTE_CLOSE = _core(PN_CONNECTION_REMOTE_CLOSE, "on_connection_remote_close")
173 CONNECTION_FINAL = _core(PN_CONNECTION_FINAL, "on_connection_final")
174
175 SESSION_INIT = _core(PN_SESSION_INIT, "on_session_init")
176 SESSION_LOCAL_OPEN = _core(PN_SESSION_LOCAL_OPEN, "on_session_local_open")
177 SESSION_LOCAL_CLOSE = _core(PN_SESSION_LOCAL_CLOSE, "on_session_local_close")
178 SESSION_REMOTE_OPEN = _core(PN_SESSION_REMOTE_OPEN, "on_session_remote_open")
179 SESSION_REMOTE_CLOSE = _core(PN_SESSION_REMOTE_CLOSE, "on_session_remote_close")
180 SESSION_FINAL = _core(PN_SESSION_FINAL, "on_session_final")
181
182 LINK_INIT = _core(PN_LINK_INIT, "on_link_init")
183 LINK_LOCAL_OPEN = _core(PN_LINK_LOCAL_OPEN, "on_link_local_open")
184 LINK_LOCAL_CLOSE = _core(PN_LINK_LOCAL_CLOSE, "on_link_local_close")
185 LINK_LOCAL_DETACH = _core(PN_LINK_LOCAL_DETACH, "on_link_local_detach")
186 LINK_REMOTE_OPEN = _core(PN_LINK_REMOTE_OPEN, "on_link_remote_open")
187 LINK_REMOTE_CLOSE = _core(PN_LINK_REMOTE_CLOSE, "on_link_remote_close")
188 LINK_REMOTE_DETACH = _core(PN_LINK_REMOTE_DETACH, "on_link_remote_detach")
189 LINK_FLOW = _core(PN_LINK_FLOW, "on_link_flow")
190 LINK_FINAL = _core(PN_LINK_FINAL, "on_link_final")
191
192 DELIVERY = _core(PN_DELIVERY, "on_delivery")
193
194 TRANSPORT = _core(PN_TRANSPORT, "on_transport")
195 TRANSPORT_ERROR = _core(PN_TRANSPORT_ERROR, "on_transport_error")
196 TRANSPORT_HEAD_CLOSED = _core(PN_TRANSPORT_HEAD_CLOSED, "on_transport_head_closed")
197 TRANSPORT_TAIL_CLOSED = _core(PN_TRANSPORT_TAIL_CLOSED, "on_transport_tail_closed")
198 TRANSPORT_CLOSED = _core(PN_TRANSPORT_CLOSED, "on_transport_closed")
199
200
201 REACTOR_INIT = _internal("reactor_init")
202 REACTOR_QUIESCED = _internal("reactor_quiesced")
203 REACTOR_FINAL = _internal("reactor_final")
204
205 SELECTABLE_INIT = _internal("selectable_init")
206 SELECTABLE_UPDATED = _internal("selectable_updated")
207 SELECTABLE_READABLE = _internal("selectable_readable")
208 SELECTABLE_WRITABLE = _internal("selectable_writable")
209 SELECTABLE_EXPIRED = _internal("selectable_expired")
210 SELECTABLE_ERROR = _internal("selectable_error")
211 SELECTABLE_FINAL = _internal("selectable_final")
212
213 @staticmethod
215 if impl is None:
216 return None
217
218 number = pn_event_type(impl)
219 cls = pn_event_class(impl)
220
221 if cls:
222 clsname = pn_class_name(cls)
223 context = wrappers[clsname](pn_event_context(impl))
224
225
226
227 if cls == PN_PYREF and isinstance(context, EventBase):
228 return context
229 else:
230 clsname = None
231
232 event = Event(impl, number, clsname, context)
233 return event
234
235 - def __init__(self, impl, number, clsname, context):
268
269 @property
272
273 @property
275 """Returns the context object associated with the event. The type of this depends on the type of event."""
276 return self._context
277
278 @property
280 l = self.link
281 if l:
282 h = l.handler
283 if h:
284 return h
285 s = self.session
286 if s:
287 h = s.handler
288 if h:
289 return h
290 c = self.connection
291 if c:
292 h = c.handler
293 if h:
294 return h
295 c = self.context
296 if not c or not hasattr(c, 'handler'):
297 return None
298 h = c.handler
299 return h
300
301 @property
303 """
304 Deprecated: Returns the container (was reactor) associated with the event.
305 """
306 return self.container
307
308 @property
310 """
311 Returns the container associated with the event.
312 """
313 return self._transport._reactor
314
316 """
317 This will look for a property of the event as an attached context object of the same
318 type as the property (but lowercase)
319 """
320 c = self.context
321
322 if type(c).__name__.lower() == name or name in [x.__name__.lower() for x in type(c).__bases__]:
323 return c
324
325
326 return getattr(c, name, None)
327
328 @property
330 """Returns the transport associated with the event, or null if none is associated with it."""
331 return self._transport
332
333 @property
335 """Returns the connection associated with the event, or null if none is associated with it."""
336 return self._connection
337
338 @property
340 """Returns the session associated with the event, or null if none is associated with it."""
341 return self._session
342
343 @property
345 """Returns the link associated with the event, or null if none is associated with it."""
346 return self._link
347
348 @property
350 """Returns the sender link associated with the event, or null if
351 none is associated with it. This is essentially an alias for
352 link(), that does an additional check on the type of the
353 link."""
354 l = self.link
355 if l and l.is_sender:
356 return l
357 else:
358 return None
359
360 @property
362 """Returns the receiver link associated with the event, or null if
363 none is associated with it. This is essentially an alias for
364 link(), that does an additional check on the type of the link."""
365 l = self.link
366 if l and l.is_receiver:
367 return l
368 else:
369 return None
370
371 @property
373 """Returns the delivery associated with the event, or null if none is associated with it."""
374 return self._delivery
375
379 if obj is None:
380 return self
381 ret = []
382 obj.__dict__['handlers'] = ret
383 return ret
384
396