如何在Rails应用程序中启动pubsub订阅者

时间:2013-05-22 20:29:06

标签: ruby-on-rails ruby redis publish-subscribe

我有一个Rails(网络)应用程序,我需要添加(redis)pub / sub订阅者。

下面是我的PubsubSubscriber课程,我需要启动该应用程序启动。

redis连接在resque.rb初始化程序文件中创建。连接后我尝试了PubsubSubscriber.new,但是当我尝试启动rails服务器时,它挂起:

=> 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

与服务器成功启动时相反:

=> 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

当我尝试在初始化程序中实例化PubsubSubscriber类时,知道服务器挂起的原因吗?有没有更好的地方开始这个?


# 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

1 个答案:

答案 0 :(得分:4)

您遇到的一个问题是,当您处于初始化程序时,EventMachine尚未就绪。因此,在EM.next_tick中包装初始化会延迟代码,直到EventMachine准备就绪:

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

当我尝试这个时,我的服务器一直启动...然后在调用$ redis.psubscribe时被阻止。

但是,切换到em-hiredis有效:

# 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  

这是因为标准的redis gem没有通过EventMachine接口监听事件 - 它只是创建与redis服务器的连接,然后阻止其他所有事件。

为了利用EM,您需要建立一个简单的连接,形式为:

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

我在这个要点中得到了一个有效的例子:https://gist.github.com/wheeyls/5647713

em-hiredis是使用此界面的redis客户端。