在退出时优雅地取消订阅 redis
Gracefully unsubscribe from redis at exit
我有一个 ruby 程序监听一个 redis 频道:
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 example in redis-rb
添加后 trap('SIGTERM') { exit }
问题得到解决
现在我的听众 class 看起来像这样:
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 频道:
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 example in redis-rb
添加后 trap('SIGTERM') { exit }
问题得到解决
现在我的听众 class 看起来像这样:
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