Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions lib/mongo/retryable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,19 @@ def read_with_retry(session = nil)
#
# @note This only retries read operations on socket errors.
#
# @param [ Hash ] options Options.
# @param [ Proc ] block The block to execute.
#
# @option options [ String ] :retry_message Message to log when retrying.
#
# @return [ Result ] The result of the operation.
#
# @since 2.2.6
def read_with_one_retry
def read_with_one_retry(options = nil)
yield
rescue Error::SocketError, Error::SocketTimeoutError
rescue Error::SocketError, Error::SocketTimeoutError => e
retry_message = options && options[:retry_message]
log_retry(e, message: retry_message)
yield
end

Expand Down Expand Up @@ -200,8 +205,13 @@ def legacy_write_with_retry(server = nil, session = nil)
end

# Log a warning so that any application slow down is immediately obvious.
def log_retry(e)
Logger.logger.warn "Retry due to: #{e.class.name} #{e.message}"
def log_retry(e, options = nil)
message = if options && options[:message]
options[:message]
else
"Retry"
end
Logger.logger.warn "#{message} due to: #{e.class.name} #{e.message}"
end
end
end
6 changes: 5 additions & 1 deletion lib/mongo/server/monitor/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def initialize(address, options = {})
# @since 2.2.0
def ismaster
ensure_connected do |socket|
read_with_one_retry do
read_with_one_retry(retry_message: retry_message) do
socket.write(ISMASTER_BYTES)
Protocol::Message.deserialize(socket).documents[0]
end
Expand Down Expand Up @@ -212,6 +212,10 @@ def handshake!
reply
end
end

def retry_message
"Retrying ismaster on #{address}"
end
end
end
end
Expand Down
42 changes: 42 additions & 0 deletions spec/mongo/server/monitor/connection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,46 @@
end
end
end

describe '#ismaster' do
let(:options) do
SpecConfig.instance.test_options
end

let(:result) { connection.ismaster }

it 'returns a hash' do
expect(result).to be_a(Hash)
end

it 'is successful' do
expect(result['ok']).to eq(1.0)
end

context 'network error during ismaster' do
let(:result) do
connection

socket = connection.send(:socket).send(:socket)
expect([Socket, OpenSSL::SSL::SSLSocket]).to include(socket.class)

expect(socket).to receive(:write).and_raise(IOError)
expect(socket).to receive(:write).and_call_original

connection.ismaster
end

it 'retries ismaster and is successful' do
expect(result).to be_a(Hash)
expect(result['ok']).to eq(1.0)
end

it 'logs the retry' do
expect(Mongo::Logger.logger).to receive(:warn) do |msg|
expect(msg).to match(/Retrying ismaster on #{connection.address}/)
end
expect(result).to be_a(Hash)
end
end
end
end