Search code examples
ruby-on-railsherokurabbitmqamqpbunny

sneaker is not receiving messages on heroku - RabbitMQ Bigwig


I am trying to run message queues on heroku. For this I am using RabbitMQ Bigwig plugin.

I am publishing messages using bunny gem and trying to receive messages with sneakers gem. This whole setup works smoothly on local machine.

I take following steps to setup queue

I run this rake on server to setup queue:

namespace :rabbitmq do
    desc 'Setup routing'
    task :setup_test_commands_queue do
      require 'bunny'

      conn = Bunny.new(ENV['SYNC_AMQP'], read_timeout: 10, heartbeat: 10)
      conn.start

      ch = conn.create_channel

      # get or create exchange
      x = ch.direct('testsync.pcc', :durable => true)

      # get or create queue (note the durable setting)
      queue = ch.queue('test.commands', :durable => true, :ack => true, :routing_key => 'test_cmd')

      # bind queue to exchange
      queue.bind(x, :routing_key => 'test_cmd')

      conn.close
    end
  end

I am able to see this queue in rabbitmq management plugin with mentioned binding.

class TestPublisher
  def self.publish(test)
    x = channel.direct("testsync.pcc", :durable => true)
    puts "publishing this = #{Test}"
    x.publish(Test, :persistent => true, :routing_key => 'pcc_cmd')
  end

  def self.channel
    @channel ||= connection.create_channel
  end

  def self.connection
    @conn = Bunny.new(ENV['RABBITMQ_BIGWIG_TX_URL'], read_timeout: 10, heartbeat: 10) # getting configuration from rabbitmq.yml
    @conn.start
  end
end

I am calling TestPublisher.publish() to publish message.

I have sneaker worker like this:

require 'test_sync'
class TestsWorker
  include Sneakers::Worker
  from_queue "test.commands", env: nil

  def work(raw_event)
    puts "^"*100
    puts raw_event
    # o = CaseNote.create!(content: raw_event, creator_id: 1)
    # puts "#########{o}"
    test = Oj.load raw_event
    test.execute
    # event_params = JSON.parse(raw_event)
    # SomeWiseService.build.call(event_params)
    ack!
  end
end

My Procfile

web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
worker:  bundle exec rake jobs:work
sneaker: WORKERS=TestsWorker bundle exec rake sneakers:run

My Rakefile

require File.expand_path('../config/application', __FILE__)
require 'rake/dsl_definition'
require 'rake'
require 'sneakers/tasks'

Test::Application.load_tasks

My sneaker configuration

require 'sneakers'
Sneakers.configure  amqp: ENV['RABBITMQ_BIGWIG_RX_URL'],
                    log: "log/sneakers.log",
                    threads: 1,
                    workers: 1

puts "configuring sneaker"

I am sure that message gets published. I am able to get message on rabbitmq management plugin. But sneaker does not work. There is nothing in sneakers.log that can help.

sneakers.log on heroku :

# Logfile created on 2016-04-05 14:40:59 +0530 by logger.rb/41212

Solution

  • Sorry for this late response. I was able to get this working on heroku. When I faced this error after hours of debugging I was not able to fix it. So I rewrote all above code and I did not check what was wrong with my previous code.

    The only problem with this code and correct code is queue binding.

    I had two queues on same exchange. pcc.commands with routing key pcc_cmd and test.commands with routing key test_cmd.

    I was working with test_cmd but as per following line in TestPublisher

    x.publish(Test, :persistent => true, :routing_key => 'pcc_cmd')
    

    I was publishing to different queue(pcc.commands). Hence I was not able to recieve the message on test.commands queue.

    In TestWorker

    from_queue "test.commands", env: nil
    

    This states that fetch messages only from test.commands queue.

    Regarding sneakers.log file: Above setup was not able to give me logs in sneakers.log file. Yes this setup works on your local development machine, but it was not working on heroku. Now days to debug such issue I ommit log attribute from configuration. like this:

    require 'sneakers'
    Sneakers.configure  amqp: ENV['RABBITMQ_BIGWIG_RX_URL'],
                      # log: "log/sneakers.log",
                      threads: 1,
                      workers: 1
    

    This way you will get sneaker logs (even heartbeat logs) in heroku logs which can be seen by running command heroku logs -a app_name --tail.