Skip to content

Commit

Permalink
Merge branch 'master' into implement_lru_cache
Browse files Browse the repository at this point in the history
  • Loading branch information
pushrax committed Jun 14, 2019
2 parents 0d55fb6 + b6b8441 commit 43efef8
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ before_install:
- scripts/install_toxiproxy.sh

rvm:
- '2.3.1'
- '2.4'
- '2.5'
- '2.6'

gemfile:
- gemfiles/mysql2-0-4-10.gemfile
Expand Down
6 changes: 5 additions & 1 deletion lib/semian/mysql2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ module Mysql2
/MySQL client is not connected/i,
)

TIMEOUT_ERROR = Regexp.union(
/Timeout waiting for a response/i,
)

ResourceBusyError = ::Mysql2::ResourceBusyError
CircuitOpenError = ::Mysql2::CircuitOpenError
PingFailure = Class.new(::Mysql2::Error)
Expand Down Expand Up @@ -118,7 +122,7 @@ def connect(*args)
def acquire_semian_resource(*)
super
rescue ::Mysql2::Error => error
if error.message =~ CONNECTION_ERROR || error.is_a?(PingFailure)
if error.message =~ CONNECTION_ERROR || error.message =~ TIMEOUT_ERROR || error.is_a?(PingFailure)
semian_resource.mark_failed(error)
error.semian_identifier = semian_identifier
end
Expand Down
6 changes: 5 additions & 1 deletion lib/semian/redis.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def connect
begin
raw_connect
rescue SocketError, RuntimeError => e
raise ResolveError.new(semian_identifier) if (e.cause || e).to_s =~ /(can't resolve)|(name or service not known)/i
raise ResolveError.new(semian_identifier) if dns_resolve_failure?(e.cause || e)
raise
end
end
Expand All @@ -111,6 +111,10 @@ def raise_if_out_of_memory(reply)
return unless reply.message =~ /OOM command not allowed when used memory > 'maxmemory'\.\s*\z/
raise ::Redis::OutOfMemoryError.new(reply.message)
end

def dns_resolve_failure?(e)
e.to_s.match?(/(can't resolve)|(name or service not known)|(nodename nor servname provided, or not known)|(failure in name resolution)/i)
end
end
end

Expand Down
25 changes: 25 additions & 0 deletions test/mysql2_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,31 @@ def test_query_errors_does_not_open_the_circuit
end
end

def test_read_timeout_error_open_the_circuit
client = connect_to_mysql!

(ERROR_THRESHOLD).times do
assert_raises Mysql2::Error do
# Should raise an exception like -
# Mysql2::Error Exception: [mysql_testing] Timeout waiting for a response from the last query. (waited 2 seconds)
client.query('SELECT sleep(5)')
end
end

assert_raises Mysql2::CircuitOpenError do
client.query('SELECT sleep(5)')
end

# After Mysql2::CircuitOpenError check regular queries are working fine.
query_string = "1 + 1"
result = nil
Timecop.travel(ERROR_TIMEOUT + 1) do
result = client.query("SELECT #{query_string};")
end

assert_equal 2, result.first[query_string]
end

def test_connect_instrumentation
notified = false
subscriber = Semian.subscribe do |event, resource, scope, adapter|
Expand Down
16 changes: 16 additions & 0 deletions test/redis_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,22 @@ def test_dns_resolution_failures_open_circuit
end
end

[
"Temporary failure in name resolution",
"Can't resolve example.com",
"name or service not known",
"Could not resolve hostname example.com: nodename nor servname provided, or not known",
].each do |message|
test_suffix = message.gsub(/\W/, '_').downcase
define_method(:"test_dns_resolution_failure_#{test_suffix}") do
Redis::Client.any_instance.expects(:raw_connect).raises(message)

assert_raises Redis::ResolveError do
connect_to_redis!(host: 'example.com')
end
end
end

def test_circuit_breaker_on_connect
@proxy.downstream(:latency, latency: 500).apply do
background { connect_to_redis! }
Expand Down
2 changes: 2 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
require 'tempfile'
require 'fileutils'
require 'byebug'
require 'mocha'
require 'mocha/minitest'

require 'helpers/background_helper'
require 'helpers/circuit_breaker_helper'
Expand Down

0 comments on commit 43efef8

Please sign in to comment.