How to start a pubsub subscription in a Rails application

I have a Rails (web) application that I need to add (redis) pub / sub subscriber.

Below is my PubsubSubscriber class that I need to run, the application starts.

The redis connection is created in the resque.rb initialization file. I tried PubsubSubscriber.new after connecting, but when I try to start the rails server it freezes:

=> Booting Thin => Rails 3.2.13 application starting in development on http://0.0.0.0:5000 => Call with -d to detach => Ctrl-C to shutdown server 

Unlike when the server starts successfully:

 => Booting Thin => Rails 3.2.13 application starting in development on http://0.0.0.0:5000 => Call with -d to detach => Ctrl-C to shutdown server >> Thin web server (v1.5.1 codename Straight Razor) >> Maximum connections set to 1024 >> Listening on 0.0.0.0:5000, CTRL+C to stop 

Any idea why the server freezes when I try to instantiate the PubsubSubscriber class in the initializer? Is there a better place to start?


 # example modified from https://github.com/redis/redis-rb/blob/master/examples/pubsub.rb class PubsubSubscriber def initialize $redis.psubscribe( :channel_one ) do |on| on.psubscribe do |event, total| end on.pmessage do |pattern, event, message| # message received, kick off some workers end on.punsubscribe do |event, total| end end end end 
+6
source share
1 answer

One of the problems you are facing is that EventMachine is not ready yet when you are in the initializer. Thus, completing your initialization in EM.next_tick will delay your code until EventMachine is ready:

 EM.next_tick { ... EventMachine code here ... } 

When I tried this, my server was fully started ... and then locked when the $ redis.psubscribe call was launched.

However, switching to em-hiredis worked:

 # config/initializers/redis_pubsub.rb EM.next_tick do $emredis = EM::Hiredis.connect(uri) $emredis.pubsub.subscribe('channelone') do |message| Rails.logger.debug message end end 

This is because the standard redis gem does not listen for events through the EventMachine interface - it simply creates a connection to your redis server and blocks everything else.

To use EM, you will need to establish a simple connection in the form:

 class RedisConnection # connect to redis def connect(host, port) EventMachine.connect host, port, self end def post_init # send subscribe channel_one to redis end def receive_data(data) # channel_one messages will arrive here end end 

This example has a working example: https://gist.github.com/wheeyls/5647713

em-hiredis is a redis client that uses this interface.

+4
source

Source: https://habr.com/ru/post/945628/


All Articles