Ruby和Redis:为订阅设置超时

时间:2014-10-29 06:56:05

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

我想在Redis频道中等待最多2秒的消息,然后我希望订阅过期/超时并停止阻止我的代码。

redis = Redis.new

redis.subscribe(channel) do |on|
  on.message do |channel, message|
    # ...
  end
end

# This line is never reached if no message is sent to channel :(

我正在使用https://github.com/redis/redis-rb。我在源代码中搜索但没有找到订阅的超时选项。

3 个答案:

答案 0 :(得分:4)

你可以像这样添加一个超时块​​:

require 'timeout'

begin
  Timeout.timeout(2) do      
    redis.subscribe(channel) do |on|
      on.message do |channel, message|
        # ...
      end
    end
  end
rescue Timeout::Error
  # handle error: show user a message?
end

答案 1 :(得分:3)

您现在可以一步subscribe with a timeout

redis.subscribe_with_timeout(5, channel) do |on|
  on.message do |channel, message|
    # ...
  end
end

答案 2 :(得分:2)

redis-rb pubsub实现中没有超时选项。但是,使用您已有的工具可以很容易地构建它:

require 'redis'

channel = 'test'
timeout_channel = 'test_timeout'

timeout = 3

redis = Redis.new

redis.subscribe(channel, time_channel) do |on|
  timeout_at = Time.now + timeout

  on.message do |channel, message|
    redis.unsubscribe if channel == timeout_channel && Time.now >= timeout_at
  end

  # not the best way to do it, but we need something publishing to timeout_channel
  Thread.new {
    sleep timeout
    Redis.new.publish timeout_channel, 'ping'
  }
end

#This line is never reached if no message is sent to channel :(
puts "here we are!"

这里的主要想法是偶尔将消息发布到单独的频道。订阅客户端还订阅该特殊频道并检查当前时间以确定它是否已超时。