Skip to content

CSHARP-3537: CSOT: retryable reads and writes #1717

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

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

sanych-sun
Copy link
Member

No description provided.

@sanych-sun sanych-sun requested a review from a team as a code owner June 25, 2025 17:00
@sanych-sun sanych-sun requested review from papafe and removed request for a team June 25, 2025 17:00
@sanych-sun sanych-sun requested review from adelinowona and BorisDog and removed request for papafe June 25, 2025 17:04
@@ -88,73 +80,82 @@ public RetryableWriteContext(IWriteBinding binding, bool retryRequested)
public IChannelSourceHandle ChannelSource => _channelSource;
public bool RetryRequested => _retryRequested;

public void DisableRetriesIfAnyWriteRequestIsNotRetryable(IEnumerable<WriteRequest> requests)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it turned out none of request.IsRetryable is using ConnectionDescription, so I've decided to remove this method and calculate _retryRequested upfront before the context creation.

}
}
}

public void Dispose()
internal async Task InitializeAsync(OperationContext operationContext, IReadOnlyCollection<ServerDescription> deprioritizedServers)
Copy link
Member Author

@sanych-sun sanych-sun Jun 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initialize and InitializeAsync are internal now, because they have retry logic, that is also useful on operation retry, when we replacing the channel. Might need to be renamed though, because OperationExecutor could call this method several times.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it needs a better naming.

catch (Exception ex) when (ShouldThrowOriginalException(ex))
{
throw originalException;
HashSet<ServerDescription> deprioritizedServers = null;
Copy link
Member Author

@sanych-sun sanych-sun Jun 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accordingly to spec's pseudo code we should provide only one previous server on retry in the list of deprioritized servers, but as it was discussed in the feature channel - we ought to maintain the list of previously attempted servers, because the original code was created when there was only 1 retry. At least Java and Python maintain the list as well.

while (true)
{
operationContext.ThrowIfTimedOutOrCanceled();
var server = context.ChannelSource.ServerDescription;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to preserve the server description BEFORE the operation, because in case of exception server's description might be reset, but we need the original one to determinate if the operation could be retried.

}
catch (Exception ex)
{
var innerException = ex is MongoAuthenticationException mongoAuthenticationException ? mongoAuthenticationException.InnerException : ex;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not to continue extracting the exception in ShouldRetryOperation? Just to reuse the code.
Then you also can keep using the When pattern, so more compact code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}
}
}

public void Dispose()
internal async Task InitializeAsync(OperationContext operationContext, IReadOnlyCollection<ServerDescription> deprioritizedServers)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it needs a better naming.

@sanych-sun sanych-sun requested a review from BorisDog June 26, 2025 20:26
Copy link
Contributor

@BorisDog BorisDog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

{
internal static class OperationContextExtensions
{
public static bool IsOperationTimeoutConfigured(this OperationContext operationContext)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IsRootContextTimeoutConfigured?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants