ruby - 在退出时优雅地取消订阅 redis

标签 ruby redis application-restart hiredis

我有一个监听 redis channel 的 ruby​​ 程序:

module Listener
  class << self
    def listen
      redis.subscribe "messaging" do |on|
        on.message do |_, msg|
          Notify.about(msg)
        end
      end
    end

    def redis
      @redis ||= Redis.new(driver: :hiredis)
    end
  end
end

每次部署应用程序时,我都会重新启动进程

kill -15 listener-pid

但是Airbrake使用以下回溯通知我关于 SignalException: SIGTERM

/gems/hiredis-0.6.1/lib/hiredis/ext/connection.rb:19 in read
/gems/hiredis-0.6.1/lib/hiredis/ext/connection.rb:19 in read
/gems/redis-3.3.3/lib/redis/connection/hiredis.rb:54 in read
/gems/redis-3.3.3/lib/redis/client.rb:262 in block in read
/gems/redis-3.3.3/lib/redis/client.rb:250 in io
/gems/redis-3.3.3/lib/redis/client.rb:261 in read
/gems/redis-3.3.3/lib/redis/client.rb:136 in block (3 levels) in call_loop
/gems/redis-3.3.3/lib/redis/client.rb:135 in loop
/gems/redis-3.3.3/lib/redis/client.rb:135 in block (2 levels) in call_loop
/gems/redis-3.3.3/lib/redis/client.rb:231 in block (2 levels) in process
/gems/redis-3.3.3/lib/redis/client.rb:367 in ensure_connected
/gems/redis-3.3.3/lib/redis/client.rb:221 in block in process
/gems/redis-3.3.3/lib/redis/client.rb:306 in logging
/gems/redis-3.3.3/lib/redis/client.rb:220 in process
/gems/redis-3.3.3/lib/redis/client.rb:134 in block in call_loop
/gems/redis-3.3.3/lib/redis/client.rb:280 in with_socket_timeout
/gems/redis-3.3.3/lib/redis/client.rb:133 in call_loop
/gems/redis-3.3.3/lib/redis/subscribe.rb:43 in subscription
/gems/redis-3.3.3/lib/redis/subscribe.rb:12 in subscribe
/gems/redis-3.3.3/lib/redis.rb:2765 in _subscription
/gems/redis-3.3.3/lib/redis.rb:2143 in block in subscribe
/gems/redis-3.3.3/lib/redis.rb:58 in block in synchronize
/usr/lib/ruby/2.4.0/monitor.rb:214 in mon_synchronize
/gems/redis-3.3.3/lib/redis.rb:58 in synchronize
/gems/redis-3.3.3/lib/redis.rb:2142 in subscribe

是否可以优雅地重新启动监听器进程,这样我就不会收到 SIGTERM 错误?

最佳答案

我找到了一个 pubsub redis-rb 中的示例

在我添加 trap('SIGTERM') { exit } 之后,问题就解决了

现在我的监听类看起来像这样:

module Listener
  class << self
    def listen
      trap('SIGTERM') { exit }

      redis.subscribe "messaging" do |on|
        on.message do |_, msg|
          Notify.about(msg)
        end
      end
    end

    def redis
      @redis ||= Redis.new(driver: :hiredis)
    end
  end
end

关于ruby - 在退出时优雅地取消订阅 redis,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46098869/

相关文章:

android - 重新启动应用程序会从我关闭它的地方开始——而不是从一开始

ruby-on-rails - ActionMailer 最佳实践 : Call method in the model or the controller?

node.js - socket.io redis 和内存泄漏

node.js - 从nodejs直接(非tcp)连接到redis

azure - 启用 Azure Redis 异地复制后的连接字符串是什么

c++ - 如何重新启动我自己的 qt 应用程序?

iis - 如何防止 IIS 在不使用时关闭网站?

ruby - 如何打开一个文件并搜索一个词?

Ruby Axlsx 真正的列自动宽度?

ruby-on-rails - 使用子存在验证创建父子 Factory Girl