title: How to implement RPC with RabbitMQ in Rails?
body: <p>I want to implement an action that calls remote service with RabbitMQ and presents returned data. I implemented this (more as a proof of concept so far) in similar way to example taken from here: <a href="https://github.com/baowen/RailsRabbit" rel="nofollow">https://github.com/baowen/RailsRabbit</a> and it looks like this:</p>
  
  <p>controller:</p>
  
  <pre><code>def rpc
    text = params[:text]
    c = RpcClient.new('RPC server route key')
    response = c.call text
    render text: response
  end
  </code></pre>
  
  <p>RabbitMQ RPC client:</p>
  
  <pre><code>class RpcClient &lt; MQ
    attr_reader :reply_queue
    attr_accessor :response, :call_id
    attr_reader :lock, :condition
  
    def initialize()
      # initialize exchange:
  
      conn = Bunny.new(:automatically_recover =&gt; false)
      conn.start
      ch = conn.create_channel
  
      @x = ch.default_exchange
      @reply_queue = ch.queue("", :exclusive =&gt; true)
      @server_queue = 'rpc_queue'
  
      @lock = Mutex.new
      @condition = ConditionVariable.new
      that = self
  
      @reply_queue.subscribe do |_delivery_info, properties, payload|
        if properties[:correlation_id] == that.call_id
          that.response = payload.to_s
          that.lock.synchronize { that.condition.signal }
        end
      end
    end
  
    def call(message)
      self.call_id = generate_uuid
      @x.publish(message.to_s,
                 routing_key: @server_queue,
                 correlation_id: call_id,
                 reply_to: @reply_queue.name)
  
      lock.synchronize { condition.wait(lock) }
      response
    end
  
    private
  
    def generate_uuid
      # very naive but good enough for code
      # examples
      "#{rand}#{rand}#{rand}"
    end
  end
  </code></pre>
  
  <p>A few tests indicate that this approach works. On the other hand, this approach assumes creating a client (and subscribing to the queue) for every request on this action, which is inefficient according to the <a href="https://www.rabbitmq.com/tutorials/tutorial-six-ruby.html" rel="nofollow">RabbitMQ tutorial</a>. So I've got two questions:</p>
  
  <ol>
  <li>Is it possible to avoid creating a queue for every Rails request?</li>
  <li>How will this approach (with threads and mutex) interfere with my whole Rails environment? Is it safe to implement things this way in Rails? I'm using Puma as my web server, if it's relevant. </li>
  </ol>