Last active
August 29, 2015 13:58
-
-
Save stevehodgkiss/10204388 to your computer and use it in GitHub Desktop.
Redis issues with Timeout on Ruby 2.1.1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'redis' | |
require 'securerandom' | |
require 'timeout' | |
describe 'timeout/redis issues' do | |
def reconnect | |
$redis = Redis.new(db: 1, :port => ENV.fetch('BOXEN_REDIS_PORT', '6379')) | |
end | |
def ruby_211_timeout(sec, klass = nil) | |
return yield(sec) if sec == nil or sec.zero? | |
message = "execution expired" | |
e = Timeout::Error | |
bl = proc do |exception| | |
begin | |
x = Thread.current | |
y = Thread.start { | |
begin | |
sleep sec | |
rescue => e | |
x.raise e | |
else | |
x.raise exception, message | |
end | |
} | |
return yield(sec) | |
ensure | |
if y | |
y.kill | |
y.join # make sure y is dead. | |
end | |
end | |
end | |
if klass | |
begin | |
bl.call(klass) | |
rescue klass => e | |
bt = e.backtrace | |
end | |
else | |
bt = Timeout::ExitException.catch(message, &bl) | |
end | |
rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/o | |
bt.reject! {|m| rej =~ m} | |
level = -caller(Timeout::CALLER_OFFSET).size | |
while Timeout::THIS_FILE =~ bt[level] | |
bt.delete_at(level) | |
end | |
raise(e, message, bt) | |
end | |
def ruby_19_timeout(sec, klass = nil) | |
return yield(sec) if sec == nil or sec.zero? | |
exception = klass || Class.new(Timeout::ExitException) | |
begin | |
begin | |
x = Thread.current | |
y = Thread.start { | |
begin | |
sleep sec | |
rescue => e | |
x.raise e | |
else | |
x.raise exception, "execution expired" | |
end | |
} | |
return yield(sec) | |
ensure | |
if y | |
y.kill | |
y.join # make sure y is dead. | |
end | |
end | |
rescue exception => e | |
rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/o | |
(bt = e.backtrace).reject! {|m| rej =~ m} | |
level = -caller(Timeout::CALLER_OFFSET).size | |
while Timeout::THIS_FILE =~ bt[level] | |
bt.delete_at(level) | |
level += 1 | |
end | |
raise if klass # if exception class is specified, it | |
# would be expected outside. | |
raise Timeout::Error, e.message, e.backtrace | |
end | |
end | |
def timeout_193 | |
ruby_19_timeout(0.1) do | |
loop { $redis.keys('*') } | |
end | |
rescue Timeout::Error | |
end | |
def timeout_211 | |
ruby_211_timeout(0.1) do | |
loop { $redis.keys('*') } | |
end | |
rescue Timeout::Error | |
end | |
before do | |
reconnect | |
$redis.flushdb | |
$redis.set(key, value) | |
1000.times do | |
$redis.set('some other key', 'testing') | |
end | |
end | |
let(:key) { 'key_1' } | |
let(:value) { 'value_1' } | |
it "returns the correct value on 1.9.3's timeout implementation" do | |
timeout_193 | |
expect($redis.get(key)).to eq value | |
end | |
it "returns the correct value on 2.1.1's timeout implementation" do | |
timeout_211 | |
expect($redis.get(key)).to eq value | |
end | |
end |
Author
stevehodgkiss
commented
Jan 20, 2015
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment