lib/mongo/retryable.rb in mongo-2.10.0 vs lib/mongo/retryable.rb in mongo-2.10.1
- old
+ new
@@ -204,23 +204,29 @@
unless ending_transaction || server.retry_writes?
return legacy_write_with_retry(server, session, &block)
end
+ txn_num = if session.in_transaction?
+ session.txn_num
+ else
+ session.next_txn_num
+ end
begin
- txn_num = session.in_transaction? ? session.txn_num : session.next_txn_num
yield(server, txn_num, false)
rescue Error::SocketError, Error::SocketTimeoutError => e
+ e.add_note("attempt 1")
if session.in_transaction? && !ending_transaction
- raise
+ raise e
end
retry_write(e, session, txn_num, &block)
rescue Error::OperationFailure => e
+ e.add_note("attempt 1")
if e.unsupported_retryable_write?
raise_unsupported_error(e)
elsif (session.in_transaction? && !ending_transaction) || !e.write_retryable?
- raise
+ raise e
end
retry_write(e, session, txn_num, &block)
end
end
@@ -272,20 +278,21 @@
begin
attempt += 1
server ||= select_server(cluster, ServerSelector.primary, session)
yield server
rescue Error::OperationFailure => e
+ e.add_note("attempt #{attempt + 1}")
server = nil
if attempt > client.max_write_retries
- raise
+ raise e
end
if e.write_retryable? && !(session && session.in_transaction?)
log_retry(e, message: 'Legacy write retry')
cluster.scan!(false)
retry
else
- raise
+ raise e
end
end
end
private
@@ -294,17 +301,19 @@
attempt = 0
server = select_server(cluster, server_selector, session)
begin
yield server
rescue Error::SocketError, Error::SocketTimeoutError => e
+ e.add_note("attempt #{attempt + 1}")
if session.in_transaction?
- raise
+ raise e
end
retry_read(e, server_selector, session, &block)
rescue Error::OperationFailure => e
+ e.add_note("attempt #{attempt + 1}")
if session.in_transaction? || !e.write_retryable?
- raise
+ raise e
end
retry_read(e, server_selector, session, &block)
end
end
@@ -313,27 +322,29 @@
server = select_server(cluster, server_selector, session)
begin
attempt += 1
yield server
rescue Error::SocketError, Error::SocketTimeoutError => e
+ e.add_note("attempt #{attempt + 1}")
if attempt > client.max_read_retries || (session && session.in_transaction?)
- raise
+ raise e
end
log_retry(e, message: 'Legacy read retry')
server = select_server(cluster, server_selector, session)
retry
rescue Error::OperationFailure => e
+ e.add_note("attempt #{attempt + 1}")
if cluster.sharded? && e.retryable? && !(session && session.in_transaction?)
if attempt > client.max_read_retries
- raise
+ raise e
end
log_retry(e, message: 'Legacy read retry')
sleep(client.read_retry_interval)
server = select_server(cluster, server_selector, session)
retry
else
- raise
+ raise e
end
end
end
def retry_write_allowed?(session, write_concern)
@@ -352,24 +363,31 @@
end
def retry_read(original_error, server_selector, session, &block)
begin
server = select_server(cluster, server_selector, session)
- rescue
+ rescue => e
+ original_error.add_note("later retry failed: #{e.class}: #{e}")
raise original_error
end
log_retry(original_error, message: 'Read retry')
begin
yield server, true
rescue Error::SocketError, Error::SocketTimeoutError => e
+ e.add_note("attempt 2")
raise e
rescue Error::OperationFailure => e
- raise original_error unless e.write_retryable?
+ unless e.write_retryable?
+ original_error.add_note("later retry failed: #{e.class}: #{e}")
+ raise original_error
+ end
+ e.add_note("attempt 2")
raise e
- rescue
+ rescue => e
+ original_error.add_note("later retry failed: #{e.class}: #{e}")
raise original_error
end
end
def retry_write(original_error, session, txn_num, &block)
@@ -377,18 +395,28 @@
# for the error which triggered the retry should have updated the
# server description and/or topology as necessary (specifically,
# a socket error or a not master error should have marked the respective
# server unknown). Here we just need to wait for server selection.
server = select_server(cluster, ServerSelector.primary, session)
- raise original_error unless (server.retry_writes? && txn_num)
+ unless server.retry_writes?
+ original_error.add_note('did not retry because server selected for retry does not supoprt retryable writes')
+ raise original_error
+ end
log_retry(original_error, message: 'Write retry')
yield(server, txn_num, true)
rescue Error::SocketError, Error::SocketTimeoutError => e
+ e.add_note('attempt 2')
raise e
rescue Error::OperationFailure => e
- raise original_error unless e.write_retryable?
- raise e
- rescue
+ if e.write_retryable?
+ e.add_note('attempt 2')
+ raise e
+ else
+ original_error.add_note("later retry failed: #{e.class}: #{e}")
+ raise original_error
+ end
+ rescue => e
+ original_error.add_note("later retry failed: #{e.class}: #{e}")
raise original_error
end
# This is a separate method to make it possible for the test suite to
# assert that server selection is performed during retry attempts.