Skip to content

Commit 43efef8

Browse files
committed
Merge branch 'master' into implement_lru_cache
2 parents 0d55fb6 + b6b8441 commit 43efef8

File tree

6 files changed

+54
-3
lines changed

6 files changed

+54
-3
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ before_install:
66
- scripts/install_toxiproxy.sh
77

88
rvm:
9-
- '2.3.1'
109
- '2.4'
1110
- '2.5'
11+
- '2.6'
1212

1313
gemfile:
1414
- gemfiles/mysql2-0-4-10.gemfile

lib/semian/mysql2.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ module Mysql2
2828
/MySQL client is not connected/i,
2929
)
3030

31+
TIMEOUT_ERROR = Regexp.union(
32+
/Timeout waiting for a response/i,
33+
)
34+
3135
ResourceBusyError = ::Mysql2::ResourceBusyError
3236
CircuitOpenError = ::Mysql2::CircuitOpenError
3337
PingFailure = Class.new(::Mysql2::Error)
@@ -118,7 +122,7 @@ def connect(*args)
118122
def acquire_semian_resource(*)
119123
super
120124
rescue ::Mysql2::Error => error
121-
if error.message =~ CONNECTION_ERROR || error.is_a?(PingFailure)
125+
if error.message =~ CONNECTION_ERROR || error.message =~ TIMEOUT_ERROR || error.is_a?(PingFailure)
122126
semian_resource.mark_failed(error)
123127
error.semian_identifier = semian_identifier
124128
end

lib/semian/redis.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def connect
8585
begin
8686
raw_connect
8787
rescue SocketError, RuntimeError => e
88-
raise ResolveError.new(semian_identifier) if (e.cause || e).to_s =~ /(can't resolve)|(name or service not known)/i
88+
raise ResolveError.new(semian_identifier) if dns_resolve_failure?(e.cause || e)
8989
raise
9090
end
9191
end
@@ -111,6 +111,10 @@ def raise_if_out_of_memory(reply)
111111
return unless reply.message =~ /OOM command not allowed when used memory > 'maxmemory'\.\s*\z/
112112
raise ::Redis::OutOfMemoryError.new(reply.message)
113113
end
114+
115+
def dns_resolve_failure?(e)
116+
e.to_s.match?(/(can't resolve)|(name or service not known)|(nodename nor servname provided, or not known)|(failure in name resolution)/i)
117+
end
114118
end
115119
end
116120

test/mysql2_test.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,31 @@ def test_query_errors_does_not_open_the_circuit
5656
end
5757
end
5858

59+
def test_read_timeout_error_open_the_circuit
60+
client = connect_to_mysql!
61+
62+
(ERROR_THRESHOLD).times do
63+
assert_raises Mysql2::Error do
64+
# Should raise an exception like -
65+
# Mysql2::Error Exception: [mysql_testing] Timeout waiting for a response from the last query. (waited 2 seconds)
66+
client.query('SELECT sleep(5)')
67+
end
68+
end
69+
70+
assert_raises Mysql2::CircuitOpenError do
71+
client.query('SELECT sleep(5)')
72+
end
73+
74+
# After Mysql2::CircuitOpenError check regular queries are working fine.
75+
query_string = "1 + 1"
76+
result = nil
77+
Timecop.travel(ERROR_TIMEOUT + 1) do
78+
result = client.query("SELECT #{query_string};")
79+
end
80+
81+
assert_equal 2, result.first[query_string]
82+
end
83+
5984
def test_connect_instrumentation
6085
notified = false
6186
subscriber = Semian.subscribe do |event, resource, scope, adapter|

test/redis_test.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,22 @@ def test_dns_resolution_failures_open_circuit
186186
end
187187
end
188188

189+
[
190+
"Temporary failure in name resolution",
191+
"Can't resolve example.com",
192+
"name or service not known",
193+
"Could not resolve hostname example.com: nodename nor servname provided, or not known",
194+
].each do |message|
195+
test_suffix = message.gsub(/\W/, '_').downcase
196+
define_method(:"test_dns_resolution_failure_#{test_suffix}") do
197+
Redis::Client.any_instance.expects(:raw_connect).raises(message)
198+
199+
assert_raises Redis::ResolveError do
200+
connect_to_redis!(host: 'example.com')
201+
end
202+
end
203+
end
204+
189205
def test_circuit_breaker_on_connect
190206
@proxy.downstream(:latency, latency: 500).apply do
191207
background { connect_to_redis! }

test/test_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
require 'tempfile'
99
require 'fileutils'
1010
require 'byebug'
11+
require 'mocha'
12+
require 'mocha/minitest'
1113

1214
require 'helpers/background_helper'
1315
require 'helpers/circuit_breaker_helper'

0 commit comments

Comments
 (0)