-
Notifications
You must be signed in to change notification settings - Fork 1.3k
CSHARP-5608: CSOT: Command Execution #1716
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
base: main
Are you sure you want to change the base?
Conversation
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.
Pull Request Overview
This PR introduces explicit handling of server round-trip time ("RTT") by expanding SelectServer
to return both a server and its RTT, and thread this RTT through various APIs and wire protocols to support operation timeouts and fail points.
- Update
SelectServer
andSelectServerAsync
to return(IServer server, TimeSpan roundTripTime)
. - Add
serverRoundTripTime
parameters toFailPoint.Configure
, binding constructors, andCommandWireProtocol
. - Inject RTT into command message sections for dynamic timeout calculation and update numerous tests to use the new overloads.
Reviewed Changes
Copilot reviewed 103 out of 103 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
tests/MongoDB.Driver.Tests/UnifiedTestOperations/UnifiedTargetedFailPointOperation.cs | Destructure (server, roundTripTime) and pass RTT into FailPoint.Configure |
src/MongoDB.Driver/Core/WireProtocol/CommandUsingCommandMessageWireProtocol.cs | Thread serverRoundTripTime into command creation and timeout logic |
src/MongoDB.Driver/OperationContextExtensions.cs | Add HasOperationTimeout and root context lookup |
src/MongoDB.Driver/Core/WireProtocol/CommandWireProtocol.cs | Update IWireProtocol methods to accept OperationContext and RTT |
tests/MongoDB.Driver.Tests/Core/Bindings/SingleServerReadWriteBindingTests.cs | Introduce RTT parameter in test constructors and add validation |
Comments suppressed due to low confidence (3)
src/MongoDB.Driver/Core/WireProtocol/CommandWireProtocol.cs:88
- [nitpick] The field
_serverRoundTripTime
is declared without XML doc. Add a brief comment explaining that this RTT is used for dynamic timeout calculations in command messages.
messageEncoderSettings,
src/MongoDB.Driver/Core/WireProtocol/CommandUsingCommandMessageWireProtocol.cs:381
- OperationContext does not define a
RemainingTimeout
property. You should compute the remaining time from the original timeout and elapsed time, or add a helper onOperationContext
to expose the remaining timeout.
var serverTimeout = operationContext.RemainingTimeout - _serverRoundTripTime;
src/MongoDB.Driver/Core/WireProtocol/CommandUsingCommandMessageWireProtocol.cs:630
RemainingTimeout
is not a member ofOperationContext
. Consider replacing this check with your new helper (e.g.,HasOperationTimeout
) or implement a properRemainingTimeout
getter.
if (operationContext.RemainingTimeout == Timeout.InfiniteTimeSpan)
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.
No major comments from me, just minor issues/questions
src/MongoDB.Driver/Core/WireProtocol/CommandUsingCommandMessageWireProtocol.cs
Outdated
Show resolved
Hide resolved
src/MongoDB.Driver/Core/WireProtocol/CommandUsingCommandMessageWireProtocol.cs
Show resolved
Hide resolved
EndServerSelection(expirableClusterDescription.ClusterDescription, selector, result.ServerDescription, stopwatch); | ||
return result.Server; | ||
EndServerSelection(expirableClusterDescription.ClusterDescription, selector, description, stopwatch); | ||
return (server, description.AverageRoundTripTime); |
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.
Accordingly to CSOT spec we should use MinRoundTripTime here, but CSharp driver do not track it yet, we have only AverageRoundTripTime. We decided to go with the AverageRoundTripTime and replace it on the later stages of CSOT implementation. More over there is a chance that RTT will be removed from maxTimeMs calculation at all.
Find more details in the https://jira.mongodb.org/browse/CSHARP-5627
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.
LGTM
@@ -61,10 +64,45 @@ public TimeSpan RemainingTimeout | |||
} | |||
} | |||
|
|||
[Obsolete("Do not use this property, unless it's needed to avoid breaking changes in public API")] | |||
public CancellationToken CombinedCancellationToken |
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.
We have a number of use-cases when we cannot update the interfaces, because they are public (I've run into at least 2 cases like that: IStreamFactory
and ISaslStep
), so we have to squeeze both: cancellation token itself and timeout into linked cancellation token. Having such CombinedCancellationToken
on operation context allow us to reuse instantiated CancellationTokenSource
s. Also I've marked the property as obsolete, so we easily can find all usages and replace with some interface changes in next major release.
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.
Is [Obsolete]
really useful here?
When this property is removed the compiler will tell us where it is used.
@@ -94,7 +115,7 @@ public void WaitTask(Task task) | |||
} | |||
|
|||
var timeout = RemainingTimeout; | |||
if (timeout != System.Threading.Timeout.InfiniteTimeSpan && timeout < TimeSpan.Zero) |
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.
RemainingTimeout
returns TimeSpan.Zero
if timed out now, so the check could be simplified.
{ | ||
var remainingTimeout = RemainingTimeout; | ||
if (remainingTimeout == System.Threading.Timeout.InfiniteTimeSpan) |
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.
RemainingTimeout
returns TimeSpan.Zero
if timed out now, so the check could be simplified.
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.
LGTM!
@@ -61,10 +64,45 @@ public TimeSpan RemainingTimeout | |||
} | |||
} | |||
|
|||
[Obsolete("Do not use this property, unless it's needed to avoid breaking changes in public API")] | |||
public CancellationToken CombinedCancellationToken |
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.
Is [Obsolete]
really useful here?
When this property is removed the compiler will tell us where it is used.
{ | ||
get { return _reference.Instance.Session; } | ||
} | ||
public TimeSpan RoundTripTime => _reference.Instance.RoundTripTime; |
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.
Not needed if we use ISelectedServer
interface.
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.
In fact this file probably needs NO changes.
@@ -27,25 +27,21 @@ internal sealed class ChannelReadBinding : IReadBinding | |||
private bool _disposed; | |||
private readonly ReadPreference _readPreference; | |||
private readonly IServer _server; | |||
private readonly TimeSpan _roundTripTime; |
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.
This file needs NO changes if we use the new ISelectedServer
interface.
@@ -26,24 +26,20 @@ internal sealed class ChannelReadWriteBinding : IReadWriteBinding | |||
private readonly IChannelHandle _channel; | |||
private bool _disposed; | |||
private readonly IServer _server; | |||
private readonly TimeSpan _serverRoundTripTime; |
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.
This file needs NO changes if we use the new ISelectedServer
interface.
@@ -72,7 +65,6 @@ public void Dispose() | |||
{ | |||
_reference.DecrementReferenceCount(); | |||
_disposed = true; | |||
GC.SuppressFinalize(this); |
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.
Why did you remove this line?
@@ -49,6 +49,7 @@ internal sealed class CommandUsingCommandMessageWireProtocol<TCommandResult> : I | |||
private readonly CommandResponseHandling _responseHandling; | |||
private readonly IBsonSerializer<TCommandResult> _resultSerializer; | |||
private readonly ServerApi _serverApi; | |||
private readonly TimeSpan _serverRoundTripTime; |
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.
Should name be _minRoundTripTime
?
@@ -369,6 +376,12 @@ private Type0CommandMessageSection<BsonDocument> CreateType0Section(ConnectionDe | |||
} | |||
} | |||
|
|||
if (operationContext.IsOperationTimeoutConfigured()) | |||
{ | |||
var serverTimeout = operationContext.RemainingTimeout - _serverRoundTripTime; |
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.
We need to handle the possibility that serverTimeout
will be negative here.
@@ -45,6 +44,7 @@ internal sealed class CommandWireProtocol<TCommandResult> : IWireProtocol<TComma | |||
private readonly CommandResponseHandling _responseHandling; | |||
private readonly IBsonSerializer<TCommandResult> _resultSerializer; | |||
private readonly ServerApi _serverApi; | |||
private readonly TimeSpan _serverRoundTripTime; |
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.
Should name be _minRoundTripTime
?
@@ -32,6 +32,7 @@ public static IReadBindingHandle CreateReadBinding(IClusterInternal cluster, ICo | |||
{ | |||
readBinding = new ChannelReadWriteBinding( | |||
session.CurrentTransaction.PinnedServer, | |||
session.CurrentTransaction.PinnedServerRoundTripTime, |
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.
This file needs NO changes if we use the new ISelectedServer
interface.
@@ -1003,33 +1003,33 @@ private IReadBindingHandle GetSingleServerReadBinding(OperationContext operation | |||
{ | |||
var readPreference = _options.ReadPreference ?? _database.Settings.ReadPreference; | |||
var selector = new ReadPreferenceServerSelector(readPreference); | |||
var server = _cluster.SelectServer(operationContext, selector); | |||
var binding = new SingleServerReadBinding(server, readPreference, NoCoreSession.NewHandle()); | |||
var (server, serverRoundTripTime) = _cluster.SelectServer(operationContext, selector); |
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.
This file needs NO changes if we use the new ISelectedServer
interface.
No description provided.