我如何在 Ruby 的陷阱上下文中使用 Redis 调用?
How could I use Redis calls in trap context in Ruby?
我的脚本从 redis 数据库中获取元素,最后用它做一些工作。我需要确保如果脚本以 ^C 或其他信号结束,该元素将返回到数据库中。
我正在努力
require "redis"
class Test
attr_reader :quit
def initialize
@redis = Redis.new
end
def trap_signal
trap("INT") {
puts "get ready to exit"
@redis.rpush "TestQueue", @elem # I need to be sure that @emelent always puts back in the database
@quit = true}
end
def run!
trap_signal
@elem = "test string"
@redis.rpush "TestQueue", @elem
while !quit
@redis.blpop "TestQueue", @elem
# Do some work whith @element
sleep 1
# And put it back in the database
@redis.rpush "TestQueue", @elem
end
end
end
Test.new.run!
但是出现这个错误
^Cget ready to exit
/usr/lib/ruby/2.1.0/monitor.rb:185:in `lock': can't be called from trap context (ThreadError)
from /usr/lib/ruby/2.1.0/monitor.rb:185:in `mon_enter'
from /usr/lib/ruby/2.1.0/monitor.rb:209:in `mon_synchronize'
from /home/kusayu/.gem/ruby/2.1.0/gems/redis-3.2.0/lib/redis.rb:37:in `synchronize'
from /home/kusayu/.gem/ruby/2.1.0/gems/redis-3.2.0/lib/redis.rb:991:in `rpush'
from test.rb:13:in `block in trap_signal'
from test.rb:24:in `call'
from test.rb:24:in `sleep'
from test.rb:24:in `run!'
from test.rb:32:in `<main>'
您的代码已经可以正常工作,只需从信号处理程序中删除 @redis.rpush
。
你不应该在信号处理程序中进行 运行 "heavy" 操作(无论如何你都会因此得到一个异常)。最好使用 @quit = true
之类的变量来向主循环发出结束时间的信号,然后让主循环处理适当的清理工作。
因此,如果您只是从 INT 信号处理程序中删除 @redis.rpush
,那么您将确保该元素返回到数据库中,因为主循环只会在 @quit
为 true
.
我的脚本从 redis 数据库中获取元素,最后用它做一些工作。我需要确保如果脚本以 ^C 或其他信号结束,该元素将返回到数据库中。 我正在努力
require "redis"
class Test
attr_reader :quit
def initialize
@redis = Redis.new
end
def trap_signal
trap("INT") {
puts "get ready to exit"
@redis.rpush "TestQueue", @elem # I need to be sure that @emelent always puts back in the database
@quit = true}
end
def run!
trap_signal
@elem = "test string"
@redis.rpush "TestQueue", @elem
while !quit
@redis.blpop "TestQueue", @elem
# Do some work whith @element
sleep 1
# And put it back in the database
@redis.rpush "TestQueue", @elem
end
end
end
Test.new.run!
但是出现这个错误
^Cget ready to exit
/usr/lib/ruby/2.1.0/monitor.rb:185:in `lock': can't be called from trap context (ThreadError)
from /usr/lib/ruby/2.1.0/monitor.rb:185:in `mon_enter'
from /usr/lib/ruby/2.1.0/monitor.rb:209:in `mon_synchronize'
from /home/kusayu/.gem/ruby/2.1.0/gems/redis-3.2.0/lib/redis.rb:37:in `synchronize'
from /home/kusayu/.gem/ruby/2.1.0/gems/redis-3.2.0/lib/redis.rb:991:in `rpush'
from test.rb:13:in `block in trap_signal'
from test.rb:24:in `call'
from test.rb:24:in `sleep'
from test.rb:24:in `run!'
from test.rb:32:in `<main>'
您的代码已经可以正常工作,只需从信号处理程序中删除 @redis.rpush
。
你不应该在信号处理程序中进行 运行 "heavy" 操作(无论如何你都会因此得到一个异常)。最好使用 @quit = true
之类的变量来向主循环发出结束时间的信号,然后让主循环处理适当的清理工作。
因此,如果您只是从 INT 信号处理程序中删除 @redis.rpush
,那么您将确保该元素返回到数据库中,因为主循环只会在 @quit
为 true
.