-
Notifications
You must be signed in to change notification settings - Fork 171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RUST-1064 Retry on handshake failure #598
Merged
abr-egn
merged 6 commits into
mongodb:master
from
abr-egn:RUST-1064/retry-on-handshake-failure
Mar 25, 2022
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
0a87587
update connection retry to any network error
abr-egn cb344f0
sync tests
abr-egn 4cb0055
also retry on auth
abr-egn 370ab20
sync retryable writes test
abr-egn 5cf1932
bring retry logic into spec
abr-egn 7749c95
check for retry_writes before ading retryable label
abr-egn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -332,16 +332,24 @@ impl Client { | |
Ok(c) => c, | ||
Err(mut err) => { | ||
err.add_labels_and_update_pin(None, &mut session, None)?; | ||
if err.is_read_retryable() && self.inner.options.retry_writes != Some(false) { | ||
err.add_label(RETRYABLE_WRITE_ERROR); | ||
} | ||
|
||
if err.is_pool_cleared() { | ||
kmahar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let op_retry = match self.get_op_retryability(&op, &session) { | ||
Retryability::Read => err.is_read_retryable(), | ||
Retryability::Write => err.is_write_retryable(), | ||
_ => false, | ||
}; | ||
if err.is_pool_cleared() || op_retry { | ||
return self.execute_retry(&mut op, &mut session, None, err).await; | ||
} else { | ||
return Err(err); | ||
} | ||
} | ||
}; | ||
|
||
let retryability = self.get_retryability(&conn, &op, &session).await?; | ||
let retryability = self.get_retryability(&conn, &op, &session)?; | ||
|
||
let txn_number = match session { | ||
Some(ref mut session) => { | ||
|
@@ -433,7 +441,7 @@ impl Client { | |
Err(_) => return Err(first_error), | ||
}; | ||
|
||
let retryability = self.get_retryability(&conn, op, session).await?; | ||
let retryability = self.get_retryability(&conn, op, session)?; | ||
if retryability == Retryability::None { | ||
return Err(first_error); | ||
} | ||
|
@@ -825,35 +833,49 @@ impl Client { | |
} | ||
|
||
/// Returns the retryability level for the execution of this operation. | ||
async fn get_retryability<T: Operation>( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It turns out this didn't need to be async. |
||
fn get_op_retryability<T: Operation>( | ||
&self, | ||
conn: &Connection, | ||
op: &T, | ||
session: &Option<&mut ClientSession>, | ||
) -> Result<Retryability> { | ||
if !session | ||
) -> Retryability { | ||
if session | ||
.as_ref() | ||
.map(|session| session.in_transaction()) | ||
.unwrap_or(false) | ||
{ | ||
match op.retryability() { | ||
Retryability::Read if self.inner.options.retry_reads != Some(false) => { | ||
return Ok(Retryability::Read); | ||
} | ||
Retryability::Write if conn.stream_description()?.supports_retryable_writes() => { | ||
// commitTransaction and abortTransaction should be retried regardless of the | ||
// value for retry_writes set on the Client | ||
if op.name() == CommitTransaction::NAME | ||
|| op.name() == AbortTransaction::NAME | ||
|| self.inner.options.retry_writes != Some(false) | ||
{ | ||
return Ok(Retryability::Write); | ||
} | ||
} | ||
_ => {} | ||
return Retryability::None; | ||
} | ||
match op.retryability() { | ||
Retryability::Read if self.inner.options.retry_reads != Some(false) => { | ||
Retryability::Read | ||
} | ||
// commitTransaction and abortTransaction should be retried regardless of the | ||
// value for retry_writes set on the Client | ||
Retryability::Write | ||
if op.name() == CommitTransaction::NAME | ||
|| op.name() == AbortTransaction::NAME | ||
|| self.inner.options.retry_writes != Some(false) => | ||
{ | ||
Retryability::Write | ||
} | ||
_ => Retryability::None, | ||
} | ||
} | ||
|
||
/// Returns the retryability level for the execution of this operation on this connection. | ||
fn get_retryability<T: Operation>( | ||
&self, | ||
conn: &Connection, | ||
op: &T, | ||
session: &Option<&mut ClientSession>, | ||
) -> Result<Retryability> { | ||
match self.get_op_retryability(op, session) { | ||
Retryability::Read => Ok(Retryability::Read), | ||
Retryability::Write if conn.stream_description()?.supports_retryable_writes() => { | ||
Ok(Retryability::Write) | ||
} | ||
_ => Ok(Retryability::None), | ||
} | ||
Ok(Retryability::None) | ||
} | ||
|
||
async fn update_cluster_time( | ||
|
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
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
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
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
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
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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When implementing this, I was a little surprised to learn that the SASL commands use bespoke parsing and validation rather than going through Serde integration like the rest; if there's no strong reason for that, it might be a good candidate for future cleanup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, a lot of the auth code is some of the oldest in the driver and actually predates the operation layer and much of the serde usage that exists today. I think it would definitely benefit from being cleaned up and updated. Could you file a ticket for that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filed RUST-1238.