Example #1
0
    def __init__(self, client, sink, queue_name=None):
        log.Logger.__init__(self, client)
        self._client = client
        self._sink = ISink(sink)

        self._bindings = []
        self._queue = None
        self._disconnected = False
        self._consume_deferred = None

        self._queue_name = queue_name

        self.log_name = self._queue_name
Example #2
0
class Connection(log.Logger):

    support_broadcast = True

    def __init__(self, client, sink, queue_name=None):
        log.Logger.__init__(self, client)
        self._client = client
        self._sink = ISink(sink)

        self._bindings = []
        self._queue = None
        self._disconnected = False
        self._consume_deferred = None

        self._queue_name = queue_name

        self.log_name = self._queue_name

    def initiate(self):
        d = defer.succeed(None)
        if self._queue_name is not None:
            d.addCallback(defer.drop_param,
                          self._client.define_queue, self._queue_name)
            d.addCallback(self._main_loop)
        else:
            self.warning('Queue name is None, skipping creating queue '
                         'and consumer.')
        d.addCallback(defer.override_result, self)
        return d

    ### IChannel ###

    def post(self, recipients, message):
        if not isinstance(message, BaseMessage):
            raise ValueError("Expected second argument to be "
                             "f.a.b.BaseMessage, got %r instead"
                             % (type(message), ))

        recipients = recipient.IRecipients(recipients)

        defers = []
        for recip in recipients:
            self.log('Sending message to %r', recip)
            d = self._client.publish(recip.key, recip.route, message)
            defers.append(d)
        return defer.DeferredList(defers)

    def release(self):
        self._disconnected = True
        if self._consume_deferred and not self._consume_deferred.called:
            ex = FinishConnection("Disconnecting")
            self._consume_deferred.errback(ex)
        return self._client.disconnect()

    def bind(self, route, key=None):
        recip = recipient.Recipient(key=key, route=route)
        exchange_type = 'fanout' if key is None else 'direct'
        return PersonalBinding(self, self._queue_name, recip, exchange_type)

    def get_bindings(self, route=None):
        if route is None:
            return list(self._bindings)
        return [x for x in self._bindings if x.recipient.route == route]

    ### protected ###

    def _register_binding(self, binding):
        self._bindings.append(binding)

    def _revoke_binding(self, binding):
        self._bindings.remove(binding)

    def _define_exchange(self, route, exchange_type="direct"):
        return self._client.define_exchange(route, exchange_type)

    def _create_binding(self, queue_name, route, key=None):
        return self._client.create_binding(route, queue_name, key)

    def _delete_binding(self, recipient, queue_name):
        route = recipient.route
        key = recipient.key
        return self._client.delete_binding(route, queue_name, key)

    ### private ###

    def _main_loop(self, queue):
        self._queue = queue

        def rebind(_):
            reactor.callLater(0, bind)

        def stop(reason):
            if reason.check(FinishConnection):
                self.log('Error handler: exiting, reason %r' % reason)
            else:
                reason.raiseException()

        def bind():
            if self._disconnected:
                return
            d = self._consume_queue(queue)
            d.addCallbacks(rebind, stop)

        bind()

    def _consume_queue(self, queue):

        def get_and_call_on_message(message):
            return self._sink.on_message(message)

        self._consume_deferred = queue.get()
        self._consume_deferred.addCallback(get_and_call_on_message)
        return self._consume_deferred