class Lock(MessagingHandler): def __init__(self, reactor, connection, lock_name, label=None, user_context=None): super(Lock, self).__init__(prefetch=0, auto_accept=False, auto_settle=False) self.reactor = reactor self.connection = connection self.lock_name = lock_name self.user_context = user_context self.acquired_state = False self.events = EventInjector() self.reactor.selectable(self.events) self.lock_receiver = None def destroy(self): if self.acquired_state and self.lock_receiver: self.lock_receiver.close() self.events.close() @property def is_acquired(self): return self.acquired_state def acquire(self): if self.acquired_state: raise LockException("Lock already acquired") self.lock_receiver = self.reactor.create_receiver(self.connection, self.lock_name, handler=self) def release(self): if not self.acquired_state: raise LockException("Lock not acquired") self.acquired_state = False self.lock_receiver.close() def on_link_opened(self, event): if event.receiver == self.lock_receiver and event.receiver.remote_source.address == self.lock_name: self.acquired_state = True new_event = ApplicationEvent("lock_acquired") new_event.user_context = self.user_context self.events.trigger(new_event) def on_link_error(self, event): if event.receiver == self.lock_receiver: new_event = ApplicationEvent("lock_failed") new_event.user_context = self.user_context new_event.error = event.link.remote_condition self.events.trigger(new_event) def on_link_closed(self, event): if event.receiver == self.lock_receiver and self.acquired_state: self.acquired_state = False new_event = ApplicationEvent("lock_released") new_event.user_context = self.user_context self.events.trigger(new_event)
class RequestServer(MessagingHandler): def __init__(self, reactor, connection, service_address): super(RequestServer, self).__init__(auto_accept=False, auto_settle=False) self.service_address = service_address self.reactor = reactor self.events = EventInjector() self.reactor.selectable(self.events) self.connection = connection self.service_receiver = self.reactor.create_receiver(self.connection, self.service_address, handler=self) self.reply_sender = self.reactor.create_sender(self.connection, None, handler=self) def stop(self): self.service_receiver.close() self.reply_sender.close() self.events.close() def fail(self, request, message): request.in_delivery.local.condition = Condition('sandpiper:bad-request', message) self.reject(request.in_delivery) def reply(self, request, properties={}, data=None): reply_message = Message(properties=properties, body=data, address=request.message.reply_to, correlation_id=request.message.correlation_id) request.out_delivery = self.reply_sender.send(reply_message) request.out_delivery._request = request def on_settled(self, event): try: request = event.delivery._request self.accept(request.in_delivery) except: pass def on_message(self, event): request = Request(event) request_event = ApplicationEvent("request") request_event.request = request request_event.server = self self.events.trigger(request_event)
class RequestClient(MessagingHandler): def __init__(self, reactor, connection, service_address): super(RequestClient, self).__init__() self.service_address = service_address self.reactor = reactor self.events = EventInjector() self.reactor.selectable(self.events) self.connection = connection self.service_sender = None self.reply_receiver = self.reactor.create_receiver(self.connection, dynamic=True, handler=self) self.reply_to = None self.ready = False self.cid = 1 self.contexts = {} def stop(self): self.service_sender.close() self.reply_receiver.close() self.events.close() def request(self, properties={}, body=None, user_context=None): cid = self.cid self.cid += 1 request_message = Message(properties = properties, body = body, reply_to = self.reply_to, correlation_id = cid) self.contexts[cid] = user_context dlv = self.service_sender.send(request_message) dlv._cid = cid def on_link_opened(self, event): if event.receiver == self.reply_receiver: self.reply_to = self.reply_receiver.remote_source.address self.service_sender = self.reactor.create_sender(self.connection, self.service_address, handler=self) def on_sendable(self, event): if not self.ready and event.sender == self.service_sender: self.ready = True self.events.trigger(ApplicationEvent("service_ready")) def on_rejected(self, event): dlv = event.delivery context = None if dlv._cid in self.contexts: context = self.contexts[dlv._cid] event = ApplicationEvent("request_failed") event.context = context event.error = None def on_message(self, event): reply_message = event.message cid = reply_message.correlation_id context = None if cid in self.contexts: context = self.contexts[cid] new_event = ApplicationEvent("response") new_event.properties = reply_message.properties new_event.body = reply_message.body new_event.user_context = context new_event.client = self self.events.trigger(new_event)