title: What's the best pattern to design an asynchronous RPC application using Python, Pika and AMQP?
body: <p><i>The producer module of my application is run by users who want to submit work to be done on a small cluster. It sends the subscriptions in JSON form through the RabbitMQ message broker.</i></p>
  
  <p>I have tried several strategies, and the best so far is the following, which is still not fully working:</p>
  
  <p>Each cluster machine runs a consumer module, which subscribes itself to the AMQP queue and issues a <strong>prefetch_count</strong> to tell the broker how many tasks it can run at once.</p>
  
  <p>I was able to make it work using SelectConnection from the Pika AMQP library. Both consumer and producer start two channels, one connected to each queue. The producer sends requests on channel [A] and waits for responses in channel [B], and the consumer waits for requests on channel [A] and send responses on channel [B]. It seems, however, that when the consumer runs the callback that calculates the response, it blocks, so I have only one task executed at each consumer at each time.</p>
  
  <p>What I need in the end:</p>
  
  <ol>
  <li> the consumer [A] subscribes his tasks (around 5k each time) to the cluster</li>
  <li> the broker dispatches N messages/requests for each consumer, where N is the number of concurrent tasks it can handle </li>
  <li> when a single task is finished, the consumer replies to the broker/producer with the result</li>
  <li> the producer receives the replies, update the computation status and, in the end, prints some reports </li>
  </ol>
  
  <p><strong>Restrictions:</strong></p>
  
  <ul>
  <li>If another user submits work, all of his tasks will be queued after the previous user (I guess this is automatically true from the queue system, but I haven't thought about the implications on a threaded environment)</li>
  <li>Tasks have an order to be submitted, but the order they are replied is not important</li>
  </ul>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I have studied a bit further and my actual problem seems to be that I use a simple function as callback to the pika's SelectConnection.channel.basic_consume() function. My last (unimplemented) idea is to pass a threading function, instead of a regular one, so the callback would not block and the consumer can keep listening.</p>