Esempio n. 1
0
    def __init__(self, backend):
        log.Logger.__init__(self, backend)
        self._backend = ITunnelBackend(backend)

        # Recipient -> Route
        self._routes = dict()
Esempio n. 2
0
class Tunneling(log.Logger):

    implements(IBackend, ISink)

    channel_type = 'tunnel'

    def __init__(self, backend):
        log.Logger.__init__(self, backend)
        self._backend = ITunnelBackend(backend)

        # Recipient -> Route
        self._routes = dict()

    ### public ###

    @property
    def route(self):
        return self._backend.route

    ### IBackend ###

    def initiate(self, messaging):
        self._messaging = messaging

        self._backend.connect(self)
        return defer.succeed(self)

    def is_idle(self):
        return self._backend.is_idle()

    def is_connected(self):
        return self._backend.is_connected()

    def wait_connected(self):
        return self._backend.wait_connected()

    def disconnect(self):
        self._backend.disconnect()

    def add_disconnected_cb(self, fun):
        self._backend.add_disconnected_cb(fun)

    def add_reconnected_cb(self, fun):
        self._backend.add_reconnected_cb(fun)

    def binding_created(self, binding):
        # not interested
        pass

    def binding_removed(self, binding):
        # not interested
        pass

    def create_external_route(self, backend_id, **kwargs):
        if backend_id != 'tunnel':
            return False
        # notify backend
        uri = kwargs.pop('uri')
        recp = kwargs.pop('recipient')
        self._backend.add_route(recp, uri)

        # create routing so that messages to this agent ends up here
        # instead of being sent through default sink
        routing_key = (recp.key, recp.route, )
        route = routing.Route(self, routing_key, priority=10, final=True)

        if recp in self._routes:
            self.warning("Adding the same route in tunneling for the second "
                         "time for the recipient %r. This might indicate the "
                         "problem, for now I will clean up the old routing "
                         "entry.", recp)
            self._messaging.routing.remove_route(self._routes[recp])
        self._messaging.routing.append_route(route)
        self._routes[recp] = route
        return True

    def remove_external_route(self, backend_id, **kwargs):
        if backend_id != 'tunnel':
            return False
        # notify backend
        recp = kwargs.pop('recipient')
        self._backend.routing.remove_route(recp)

        try:
            self._messaging.routing.remove_route(self._routes[recp])
            del(self._routes[recp])
        except KeyError:
            self.error("remove_external_route() called for the recipient %r "
                       "for which we don't have a route stored", recp)
        return True

    ### ISink ###

    def on_message(self, message):
        return self._backend.post(message)

    ### protected ###

    def _dispatch(self, message):
        self._messaging.dispatch(message, outgoing=False)