2

I am using the bunny gem to publish messages to a RabbitMQ.

Following the recommendation given in the official documentation for use with Passenger in Rack apps, I added connection creation to be executed after a new worker process was started.

if defined?(PhusionPassenger)
  PhusionPassenger.on_event(:starting_worker_process) do |forked|
    if forked
      # We’re in a smart spawning mode
      # Now is a good time to connect to RabbitMQ
      #
      # Every process will get it's own connection!
      $rabbitmq_connection = Bunny.new rabbit[settings.environment.to_s]
      $rabbitmq_connection.start
    end
  end
else # For non passenger environments - e.g. specs or rackup
  $rabbitmq_connection = Bunny.new rabbit[settings.environment.to_s]
  $rabbitmq_connection.start
end

This works pretty well, however when the connection is lost mid request (before the message could be published) no exception is caught. The process just seems to die and return the generic apache error page - logging doesn't work anymore either.

Thus in my specific case a database entry was created but I could not write a log message cleanly indicating that one and which message could not be published.

One workaround I found is to just create the connection to rabbitmq on a per request basis by establishing the connection directly before actually publishing the message. That doesn't seem to be very efficient though, given that passenger worker processes handle more than a single request before they are discarded. It does however properly catch the exception, log it and continue on with the request handling

def publish_message(exchange, key, message)
  rabbitmq_connection = Bunny.new $rabbit
  rabbitmq_connection.start
  ch       = rabbitmq_connection.create_channel
  exchange = ch.exchange(exchange, durable: true, type: :topic)
  exchange.publish(message, routing_key: key, persistent: true)
  ch.close
  rabbitmq_connection.close
rescue Exception => e
  $log_file.error "Sending message #{message} to #{exchange} with key #{key} failed: #{e.message}"
end

Now I am wondering how to catch this when following the recommended approach and whether there is any other best practice for Rack Apps with passenger which I just haven't found yet. I'd appreciate any hints leading me to finding a better solution than my workaround.

  • Could you ask this question on our mailing list? Bunny's author frequently replies questions there. See https://groups.google.com/forum/#!forum/rabbitmq-users – old_sound Mar 09 '15 at 19:13

0 Answers0