0

I'm building a rails app, but I need to be able to listen for events in redis.

How might I got about starting a single separate process when the rails server starts? I only ever need one instance of it running, and it shouldn't end until the rails server stops.

I tried setting up a rake task and invoking it, and the take task starts fine, but it wouldn't let puma start. There has to be a better way. This is what I have.

lib/tasks/redis_monitor.rb

namespace :redis_monitor do
  task monitor: :environment do
    $redis.subscribe('channel') do |on|
      on.message do |channel, message|
        # stuff.
      end
    end
  end
end

config/application.rb

config.after_initialize do
  Rails.application.load_tasks
  Rake::Task['redis_monitor:monitor'].invoke
end

Thanks!

  • Duplicate of https://stackoverflow.com/questions/22644761/redis-pub-sub-on-rails – Daniel Westendorf Nov 09 '17 at 20:25
  • Not quite, I tried that way and I can't get both the task and webserver running consecutively. I think it might be a problem with how I'm running the task. – testing_josh Nov 09 '17 at 20:35
  • Re-read the question and answer again, they're nearly an exact match. You'll note that the answer suggests running the rake task as a separate process, not within your Rails server, as the subscription will be blocking for the current thread. – Daniel Westendorf Nov 09 '17 at 20:41
  • Too late to edit, but: Invoking the rake task within your rails initializer is running the subscription within the same thread as your webserver. You need to run the rake task as a separate process, a la `rake redis_monitor:monitor` – Daniel Westendorf Nov 09 '17 at 20:47
  • I see, do you happen to know in which file I'd run the command from? – testing_josh Nov 09 '17 at 20:51
  • @testing_josh You need to separately run the process in the same way you are running your web server. – Aakash Gupta Nov 09 '17 at 21:12
  • Hmm... I'm trying it by just starting both processes separately. This works, but doesn't allow me to interact with my models from the rake task. I can't created/change objects. – testing_josh Nov 09 '17 at 21:21
  • I thought that is what `:environment` was doing? – testing_josh Nov 09 '17 at 21:30
  • @testing_josh Need to test few things in this regard. Will get back to you after that. – Aakash Gupta Nov 09 '17 at 21:34
  • Hmm.. not sure what's going on. If I run `puts MyModel.all` from inside the task it makes a query. There is a module method that is called from the task, and it also works there. The module is at `lib/my_module.rb`. However, when I try to call `MyModel.create_from_message` which is a custom method on the model, I get nothing. – testing_josh Nov 09 '17 at 21:47
  • Can you give a paste bin url having the actual of what you are trying to do? @testing_josh – Aakash Gupta Nov 10 '17 at 13:03
  • sure, here you go: https://pastebin.com/6kdLu6y2 – testing_josh Nov 10 '17 at 15:42
  • So, according to your code, you have used `include MessageHandler` statement in your task file and even after that, you are using `MessageHandler.method_name`. Instead of this, you should directly use method_name as including a module makes all its methods available without using ModuleName which is MessageHandler in your case. Try to change `MessageHandler.handle(data)` to `handle(data)` and check if it works or not. – Aakash Gupta Nov 11 '17 at 14:01
  • Using `handle(data)` as opposed to `MessageHandler.handle(data)` had the same effect. `Model.create_from_message` still doesn't create the record in the database. Could is have something to do with where my module is located? Does it need to be in app/lib instead of lib? – testing_josh Nov 13 '17 at 15:57

0 Answers0