Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails and MQTT: Subscribe to topic in background at server startup?

I want to subscribe to a mqtt topic in my rails app when the server starts and and keep the subscription always active and running.

I'm using this mqtt gem for mqtt communication: https://github.com/njh/ruby-mqtt

Here is what I have right now:

in application.rb:

config.after_initialize do
 mqttSub = BackgroundMQTT.new
 mqttSub.run
end

BackgroundMQTT class:

class MQTTSubscriber
  def run
    Thread.new do
      MQTT::Client.connect(:host => 'localhost', :port => 1883,) do |c|
        c.get('#') do |topic,message|
          puts "#{topic}: #{message}"
          #Do things, access activerecord etc.
        end
      end
    end
  end
end

So basically the mqtt subscription starts in the after_initialize method and as far as I know, doesn't stop automatically?

Also As you can see, I'm running the subscription in a Thread, otherwise my rails application would stop doing anything else than listening to the mqtt subscription.

This seems to work at least for the first couple of minutes.

I'm not sure if this is a recommended way of doing what I want to do. Could this cause any issues that I haven't considered? What would be a recommend way of doing this?

like image 784
user3494179 Avatar asked Aug 29 '16 11:08

user3494179


1 Answers

Two interesting notes that may help. I see the MQTT library already uses Threads and does not need your local usage.

Second, when you pass a block, there's a different behavior than if you don't. The relevant code for that behavior is at https://github.com/njh/ruby-mqtt/blob/master/lib/mqtt/client.rb#L292-L308.

I also see that you're instantiating a BackgroundMQTT class and not the MQTTSubscriber that you list in the question. I'm assuming that's just a typo.

Lastly, Rails and the Rack server affects how all of this executes. If you're trying to make sure your threading is working properly, I'd execute this outside of Rails and ensure you're getting the proper behavior before putting it into your application. If you're sure this is not related to your implementation, then I might run some tests on how long-lived Threads work inside of a Rails app. Try reducing your implementation down to just puts without the connection and see how well that behaves.

like image 120
mikegreenberg Avatar answered Oct 30 '22 07:10

mikegreenberg