Exemple #1
0
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)