Search code examples
ruby-on-railsmultithreadingunicorn

Is it possible to create a thread in Rails subscribe to Redis message channel?


I am trying to create a thread in Rails to subscribe a message channel of Redis. Is there a way to do this? I am using unicorn.

I have tried to do this in the unicorn configuration like this:

after_fork do |server, worker|

  Thread.new do
    begin
      $redis.subscribe(:one, :two) do |on|
        on.subscribe do |channel, subscriptions|
          puts "Subscribed to ##{channel} (#{subscriptions} subscriptions)"
        end
        on.message do |channel, message|
          puts "##{channel}: #{message}"
          $redis.unsubscribe if message == "exit"
        end
        on.unsubscribe do |channel, subscriptions|
          puts "Unsubscribed from ##{channel} (#{subscriptions} subscriptions)"
        end
      end
    rescue Redis::BaseConnectionError => error
      puts "#{error}, retrying in 1s"
      sleep 1
      retry
    end
  end
end

But it will make the unicorn server unable to handle any web request. I thought that if I am using a different thread to subscribe to Redis, it won't block the main thread; am I missing something here?


Solution

  • The problem here is the GIL in ruby; and the client library of Redis ruby is using a loop for the subscribe command.