ruby轨道 – Redis pub / sub在轨道上

跟随 Redis Pub/Sub

这工作正常,我可以发布消息在任何类使用

$redis.publish 'channel',{ object: @object.id }

使用redis-cli> MONITOR,我可以验证这个请求是否正确发布

[0 127.0.0.1:64192] "publish" "channel" "{:object=>\"5331d541f4eec77185000003\" }"

当我在其他类(侦听器类)中为该通道添加订阅者块时,问题开始,如下所示

class OtherClass
  $redis.subscribe('channel') do |payload|
    p payload
  end
end

在redis-cli>监听器还显示监听器正确订阅

[0 127.0.0.1:52930] "subscribe" "channel"

问题是当我将用户侦听器类添加到相同的rails应用程序…它停止工作,因为OtherClass侦听redis服务器并停止执行任何其他代码…它只是坐在那里听.

所以有一种方法可以在同一个轨道应用程序上使用redis制作消息总线,以便事件从某些类或服务对象发布,并且有特定通道的监听器可以在后台接收事件时采取行动.

我知道我可能会使用sidekiq或任何其他背景工作人员来完成这项工作,但过了一会儿后台工作人员变得凌乱而且不可维护.

解决方法

Redis#subscribe的实现是 a loop,它将控制当前线程以便收听事件.这意味着当您按照您显示的方式将订阅放入Rails类的上下文中时,引导过程将停止.

您可以尝试在线程中包装调用,但是这种方法将在每次此类加载到新进程(如rails控制台或多个独角兽)时创建一个新的订阅.另外,你必须要注意共享状态和其他线程问题.这可能不是你想要的

您最好开始加载rails环境的不同进程,并与提供Web请求的进程分开订阅redis.这可能是一个如下的耙子任务:

namespace :subscribe do
  task :redis => :environment do
    $redis.subscribe("bravo") do |on|
      on.message do |channel,message|
        Rails.logger.info("broadcast on channel #{channel}: #{message}")
        OtherClass.some_method # yada yada
      end
    end
  end
end

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...