Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
 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)