4

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
dnsh
  • 3,516
  • 2
  • 22
  • 47
  • 1
    Were you able to resolve this? One silly thing: have you assigned a dyno to sneakers process? Other than that, can you put `puts "configuring sneaker"` before the actual configuration line and see if it is displayed in logs? Also shouldn't your log on heroku contain info on dyno from which it is coming from? – draganstankovic Sep 26 '16 at 20:51
  • This might help some poor soul in the future. I was doing something similar but on `cloud66`, I had to change my procfile: from `sneaker: WORKERS=TestsWorker bundle exec rake sneakers:run` to `sneaker: bundle exec rake sneakers:run WORKERS=TestsWorker ` NOTE - the WORKERS env must come at the end – house9 Jan 20 '17 at 19:53

1 Answers1

2

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.

dnsh
  • 3,516
  • 2
  • 22
  • 47