def build_server(self, delegate, processor, handler, address, queues=None, standalone=True): processor_name = processor.__name__ log.debug("Creating new server for {0} with ID {1}".format( processor_name, address.instance)) address = IAddress(address) if not queues: queues = topology.queues if isinstance(self.channel, int): channel = yield self.client.channel(self.channel) yield channel.channel_open() else: # Assume it's already open! channel = self.channel deferreds = [] # Declare all exchanges exchanges = {} for k, e in topology.exchanges.iteritems(): e = Exchange(channel, **e) e.format_name(**dict(address)) e.declare() exchanges[k] = e self.responses = Exchange(channel, **topology.exchanges['responses']) # Declare all queues qs = [] for q in queues: q = q.copy() bindings = q.pop('bindings') q = Queue(channel, **q) q.format_name(**dict(address)) q.declare() deferreds += [q.bind(exchanges[e], k.format(**dict(address))) for e, k in bindings] qs.append(q) # Wait for declarations and bindings yield defer.DeferredList(deferreds) log.debug("All queues and needed exchanges declared and bound, start listening") tags = [] for queue in qs: tag = yield queue.consume() tags.append(tag) @defer.inlineCallbacks def destroy(ref): log.debug("Server for {0} garbage collected, removing " \ "subscriptions".format(processor_name)) try: yield defer.DeferredList([channel.basic_cancel(t) for t in tags]) except Exception as e: pass if not standalone: handler = weakref.proxy(handler, destroy) processor = processor.Processor(handler) for tag in tags: queue = yield self.client.queue(tag) self.get_next_message(channel, queue, processor, delegate)
def build_client(self, address, service=None, distribution=None, cache=True): yield self.client_lock.acquire() try: address = IAddress(address) if not service: service = utils.get_module_from_address(address) service_name = service.__name__ + address.routing_key distribution = distribution or address.distribution if not distribution: raise ValueError("The distribution mode was not defined and " \ "could not be inferred from the address.") key = (service, address.routing_key, distribution) try: client = self.clients[key] except KeyError: log.debug("Creating new client for {0} with routing key {1} and distribution {2}".format( service.__name__, address.routing_key, distribution)) if isinstance(self.channel, int): channel = yield self.client.channel(self.channel) yield channel.channel_open() else: # Assume it's already open! channel = self.channel response_exchange = Exchange(channel, **topology.exchanges['responses']) response_queue = Queue(channel, exclusive=True, auto_delete=True) yield response_queue.declare() yield response_queue.bind(response_exchange) consumer_tag = yield response_queue.consume() service_exchange = Exchange(channel, **topology.exchanges[distribution]) service_exchange.format_name(**dict(address)) yield service_exchange.declare() amqp_transport = TwistedAMQPTransport(channel, str(service_exchange), address.routing_key, service_name, str(response_queue), self.reply_to) client = service.Client(amqp_transport, self.oprot_factory) client.address = address client.factory = self if cache: weak_client = client self.clients[key] = client else: @defer.inlineCallbacks def destroy(ref): log.debug("Client for {0} garbage collected, removing " \ "subscriptions".format(service_name)) try: yield channel.basic_cancel(consumer_tag) except Exception as e: pass weak_client = weakref.proxy(client, destroy) queue = yield self.client.queue(consumer_tag) self.get_next_message(channel, queue, weak_client) queue = yield self.client.get_return_queue(service_name) self.get_next_unroutable_message(channel, queue, weak_client) else: log.debug("Using cached client for {0} with routing key {1} and distribution {2}".format( service.__name__, address.routing_key, distribution)) finally: self.client_lock.release() defer.returnValue(client)