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_SESSION_REMOTE_CLOSE, PN_SESSION_FINAL, pn_event_context, pn_collector_put, \
25 PN_SELECTABLE_UPDATED, pn_collector, PN_CONNECTION_REMOTE_OPEN, pn_event_attachments, pn_event_type, \
26 pn_collector_free, pn_handler_dispatch, PN_SELECTABLE_WRITABLE, PN_SELECTABLE_INIT, PN_SESSION_REMOTE_OPEN, \
27 pn_collector_peek, PN_CONNECTION_BOUND, PN_LINK_FLOW, pn_event_connection, PN_LINK_LOCAL_CLOSE, \
28 PN_TRANSPORT_ERROR, PN_CONNECTION_LOCAL_OPEN, PN_CONNECTION_LOCAL_CLOSE, pn_event_delivery, \
29 PN_LINK_REMOTE_OPEN, PN_TRANSPORT_CLOSED, PN_TRANSPORT_HEAD_CLOSED, PN_TRANSPORT, pn_event_reactor, \
30 PN_CONNECTION_REMOTE_CLOSE, pn_collector_pop, PN_LINK_INIT, pn_event_link, PN_CONNECTION_UNBOUND, \
31 pn_event_type_name, pn_event_session, PN_LINK_FINAL, pn_py2void, PN_REACTOR_INIT, PN_REACTOR_QUIESCED, \
32 PN_LINK_LOCAL_DETACH, PN_SESSION_INIT, PN_CONNECTION_FINAL, PN_TIMER_TASK, pn_class_name, PN_SELECTABLE_READABLE, \
33 pn_event_transport, PN_TRANSPORT_TAIL_CLOSED, PN_SELECTABLE_FINAL, PN_SESSION_LOCAL_OPEN, PN_DELIVERY, \
34 PN_SESSION_LOCAL_CLOSE, pn_event_copy, PN_REACTOR_FINAL, PN_LINK_LOCAL_OPEN, PN_SELECTABLE_EXPIRED, \
35 PN_LINK_REMOTE_DETACH, PN_PYREF, PN_LINK_REMOTE_CLOSE, pn_event_root, PN_SELECTABLE_ERROR, \
36 PN_CONNECTION_INIT, pn_event_class, pn_void2py, pn_cast_pn_session, pn_cast_pn_link, pn_cast_pn_delivery, \
37 pn_cast_pn_transport, pn_cast_pn_connection, pn_cast_pn_selectable
38
39 from ._common import Constant
40 from ._delivery import Delivery
41 from ._endpoints import Connection, Session, Link
42 from ._reactor_impl import Selectable, WrappedHandler
43 from ._transport import Transport
44 from ._wrapper import Wrapper
48
50 self._impl = pn_collector()
51
52 - def put(self, obj, etype):
53 pn_collector_put(self._impl, PN_PYREF, pn_py2void(obj), etype.number)
54
56 return Event.wrap(pn_collector_peek(self._impl))
57
59 ev = self.peek()
60 pn_collector_pop(self._impl)
61
63 pn_collector_free(self._impl)
64 del self._impl
65
66
67 if "TypeExtender" not in globals():
71
73 try:
74 return self.number
75 finally:
76 self.number += 1
77
80 _lock = threading.Lock()
81 _extended = TypeExtender(10000)
82 TYPES = {}
83
84 - def __init__(self, name=None, number=None, method=None):
85 if name is None and number is None:
86 raise TypeError("extended events require a name")
87 try:
88 self._lock.acquire()
89 if name is None:
90 name = pn_event_type_name(number)
91
92 if number is None:
93 number = self._extended.next()
94
95 if method is None:
96 method = "on_%s" % name
97
98 self.name = name
99 self.number = number
100 self.method = method
101
102 self.TYPES[number] = self
103 finally:
104 self._lock.release()
105
108
116
119
120 - def __init__(self, clazz, context, type):
124
127
128
129 -def _none(x): return None
130
131
132 DELEGATED = Constant("DELEGATED")
133
134
135 -def _core(number, method):
136 return EventType(number=number, method=method)
137
138
139 wrappers = {
140 "pn_void": lambda x: pn_void2py(x),
141 "pn_pyref": lambda x: pn_void2py(x),
142 "pn_connection": lambda x: Connection.wrap(pn_cast_pn_connection(x)),
143 "pn_session": lambda x: Session.wrap(pn_cast_pn_session(x)),
144 "pn_link": lambda x: Link.wrap(pn_cast_pn_link(x)),
145 "pn_delivery": lambda x: Delivery.wrap(pn_cast_pn_delivery(x)),
146 "pn_transport": lambda x: Transport.wrap(pn_cast_pn_transport(x)),
147 "pn_selectable": lambda x: Selectable.wrap(pn_cast_pn_selectable(x))
148 }
149
150
151 -class Event(Wrapper, EventBase):
152 REACTOR_INIT = _core(PN_REACTOR_INIT, "on_reactor_init")
153 REACTOR_QUIESCED = _core(PN_REACTOR_QUIESCED, "on_reactor_quiesced")
154 REACTOR_FINAL = _core(PN_REACTOR_FINAL, "on_reactor_final")
155
156 TIMER_TASK = _core(PN_TIMER_TASK, "on_timer_task")
157
158 CONNECTION_INIT = _core(PN_CONNECTION_INIT, "on_connection_init")
159 CONNECTION_BOUND = _core(PN_CONNECTION_BOUND, "on_connection_bound")
160 CONNECTION_UNBOUND = _core(PN_CONNECTION_UNBOUND, "on_connection_unbound")
161 CONNECTION_LOCAL_OPEN = _core(PN_CONNECTION_LOCAL_OPEN, "on_connection_local_open")
162 CONNECTION_LOCAL_CLOSE = _core(PN_CONNECTION_LOCAL_CLOSE, "on_connection_local_close")
163 CONNECTION_REMOTE_OPEN = _core(PN_CONNECTION_REMOTE_OPEN, "on_connection_remote_open")
164 CONNECTION_REMOTE_CLOSE = _core(PN_CONNECTION_REMOTE_CLOSE, "on_connection_remote_close")
165 CONNECTION_FINAL = _core(PN_CONNECTION_FINAL, "on_connection_final")
166
167 SESSION_INIT = _core(PN_SESSION_INIT, "on_session_init")
168 SESSION_LOCAL_OPEN = _core(PN_SESSION_LOCAL_OPEN, "on_session_local_open")
169 SESSION_LOCAL_CLOSE = _core(PN_SESSION_LOCAL_CLOSE, "on_session_local_close")
170 SESSION_REMOTE_OPEN = _core(PN_SESSION_REMOTE_OPEN, "on_session_remote_open")
171 SESSION_REMOTE_CLOSE = _core(PN_SESSION_REMOTE_CLOSE, "on_session_remote_close")
172 SESSION_FINAL = _core(PN_SESSION_FINAL, "on_session_final")
173
174 LINK_INIT = _core(PN_LINK_INIT, "on_link_init")
175 LINK_LOCAL_OPEN = _core(PN_LINK_LOCAL_OPEN, "on_link_local_open")
176 LINK_LOCAL_CLOSE = _core(PN_LINK_LOCAL_CLOSE, "on_link_local_close")
177 LINK_LOCAL_DETACH = _core(PN_LINK_LOCAL_DETACH, "on_link_local_detach")
178 LINK_REMOTE_OPEN = _core(PN_LINK_REMOTE_OPEN, "on_link_remote_open")
179 LINK_REMOTE_CLOSE = _core(PN_LINK_REMOTE_CLOSE, "on_link_remote_close")
180 LINK_REMOTE_DETACH = _core(PN_LINK_REMOTE_DETACH, "on_link_remote_detach")
181 LINK_FLOW = _core(PN_LINK_FLOW, "on_link_flow")
182 LINK_FINAL = _core(PN_LINK_FINAL, "on_link_final")
183
184 DELIVERY = _core(PN_DELIVERY, "on_delivery")
185
186 TRANSPORT = _core(PN_TRANSPORT, "on_transport")
187 TRANSPORT_ERROR = _core(PN_TRANSPORT_ERROR, "on_transport_error")
188 TRANSPORT_HEAD_CLOSED = _core(PN_TRANSPORT_HEAD_CLOSED, "on_transport_head_closed")
189 TRANSPORT_TAIL_CLOSED = _core(PN_TRANSPORT_TAIL_CLOSED, "on_transport_tail_closed")
190 TRANSPORT_CLOSED = _core(PN_TRANSPORT_CLOSED, "on_transport_closed")
191
192 SELECTABLE_INIT = _core(PN_SELECTABLE_INIT, "on_selectable_init")
193 SELECTABLE_UPDATED = _core(PN_SELECTABLE_UPDATED, "on_selectable_updated")
194 SELECTABLE_READABLE = _core(PN_SELECTABLE_READABLE, "on_selectable_readable")
195 SELECTABLE_WRITABLE = _core(PN_SELECTABLE_WRITABLE, "on_selectable_writable")
196 SELECTABLE_EXPIRED = _core(PN_SELECTABLE_EXPIRED, "on_selectable_expired")
197 SELECTABLE_ERROR = _core(PN_SELECTABLE_ERROR, "on_selectable_error")
198 SELECTABLE_FINAL = _core(PN_SELECTABLE_FINAL, "on_selectable_final")
199
200 @staticmethod
201 - def wrap(impl, number=None):
202 if impl is None:
203 return None
204
205 if number is None:
206 number = pn_event_type(impl)
207
208 event = Event(impl, number)
209
210
211
212 if pn_event_class(impl) == PN_PYREF and \
213 isinstance(event.context, EventBase):
214 return event.context
215 else:
216 return event
217
221
224
228
229 @property
231 cls = pn_event_class(self._impl)
232 if cls:
233 return pn_class_name(cls)
234 else:
235 return None
236
237 @property
240
241 @property
243 """Returns the context object associated with the event. The type of this depend on the type of event."""
244 return wrappers[self.clazz](pn_event_context(self._impl))
245
246 - def dispatch(self, handler, type=None):
255
256 @property
258 """Returns the reactor associated with the event."""
259 return wrappers.get("pn_reactor", _none)(pn_event_reactor(self._impl))
260
262 r = self.reactor
263 if r and hasattr(r, 'subclass') and r.subclass.__name__.lower() == name:
264 return r
265 else:
266 return super(Event, self).__getattr__(name)
267
268 @property
270 """Returns the transport associated with the event, or null if none is associated with it."""
271 return Transport.wrap(pn_event_transport(self._impl))
272
273 @property
275 """Returns the connection associated with the event, or null if none is associated with it."""
276 return Connection.wrap(pn_event_connection(self._impl))
277
278 @property
280 """Returns the session associated with the event, or null if none is associated with it."""
281 return Session.wrap(pn_event_session(self._impl))
282
283 @property
285 """Returns the link associated with the event, or null if none is associated with it."""
286 return Link.wrap(pn_event_link(self._impl))
287
288 @property
290 """Returns the sender link associated with the event, or null if
291 none is associated with it. This is essentially an alias for
292 link(), that does an additional checkon the type of the
293 link."""
294 l = self.link
295 if l and l.is_sender:
296 return l
297 else:
298 return None
299
300 @property
302 """Returns the receiver link associated with the event, or null if
303 none is associated with it. This is essentially an alias for
304 link(), that does an additional checkon the type of the link."""
305 l = self.link
306 if l and l.is_receiver:
307 return l
308 else:
309 return None
310
311 @property
313 """Returns the delivery associated with the event, or null if none is associated with it."""
314 return Delivery.wrap(pn_event_delivery(self._impl))
315
318
322 if obj is None:
323 return self
324 ret = []
325 obj.__dict__['handlers'] = ret
326 return ret
327
334