Implement the overload retry policy for commands that are read/write retryable - #2041
Conversation
Also add `UnifiedClientBackpressureTest` and enable prose tests JAVA-6248
- Removed `ClientSessionImpl.applyMajorityWriteConcernToTransactionOptions`, which was used in `withTransaction`. This is not the place for this logic, and it furthermore was useless, as `CommitTransactionOperation.getRetryCommandModifier` does the same, and more. - Made `ClientSessionImpl` and `ClientSessionPublisherImpl` compute `alreadyCommitted` the same way. - Made `ClientSessionImpl.commitTransaction` and `ClientSessionPublisherImpl.commitTransaction` handle `transactionState` and `commitInProgress` the same way. - Passed `OperationContext` instead of `TimeoutContext` to `AbortTransactionOperation.getRetryCommandModifier` JAVA-6248
JAVA-6248
f5fab08 to
15fc28b
Compare
…ot adding `startTransaction` JAVA-6248
…Operation.getRetryCommandModifier` adding `withW("majority")` when not needed
JAVA-6248
15fc28b to
f6fabe4
Compare
| * @param attemptNumber attempt number > 0 | ||
| * @return The calculated backoff in milliseconds. | ||
| */ | ||
| public static long calculateBackoffMs(final double baseMs, final double maxMs, final double growth, final int attemptNumber) { |
There was a problem hiding this comment.
VAKOTODO Make private.
| } else if (policies.containsKey(Descriptor.READ)) { | ||
| maxRetries = Descriptor.READ.maxRetries; | ||
| } else if (policies.containsKey(Descriptor.OVERLOAD)) { | ||
| maxRetries = overload().map(State.Overload::getMaxAttempts).orElse(Descriptor.OVERLOAD.maxRetries); |
There was a problem hiding this comment.
VAKOTODO Assert overload() returns non-empty Optional, because policies are never empty (see assertValid).
| int getMaxAttempts() { | ||
| return maxAttempts(maxAdaptiveRetriesSetting == null | ||
| ? IndividualPolicies.Descriptor.OVERLOAD.maxRetries | ||
| : maxAdaptiveRetriesSetting); | ||
| } |
There was a problem hiding this comment.
VAKOTODO The getMaxAttempts method is called to compute maxRetries in IndividualPolicies.getMaxAttempts, which is then converted to max attempts again via maxAttempts(maxRetries). This is wrong.
…nal` in `IndividualPolicies.getMaxAttempts`
There was a problem hiding this comment.
@vbabanin Create a ticket on refactoring BaseClientSessionImpl and its subclasses (ClientSessionImpl, ClientSessionPublisherImpl):
- We need to reduce the state and code duplication between subclasses.
- We need to split this god object into multiple objects each implemented by a different class responsible for its own area.
BaseClientSessionImpl.OverloadRetryPolicyState(BaseClientSessionImpl.overloadRetryPolicyState) is a precedent of the new state and logic being put in separate classes, andBaseClientSessionImplbeing composed of their instances.
| void closeCommitScope(); | ||
|
|
||
| /** | ||
| * A part of {@link DefaultOverloadRetryPolicyState} restricted to the execution of a command |
There was a problem hiding this comment.
VAKOTODO DefaultOverloadRetryPolicyState -> OverloadRetryPolicyState
| Throwable prospectiveFailedResult = prospectiveFailedResult(); | ||
| if (attemptFailedResult instanceof Error) { | ||
| onAttemptFatalFailure(policy, prospectiveFailedResult, (Error) attemptFailedResult); | ||
| policy.onAttemptFatalFailure(); |
There was a problem hiding this comment.
VAKOTODO Remove policy.onAttemptFatalFailure();
| } | ||
| // this `RetryControl` must not be mutated before calling `onAttemptFailure` | ||
| Decision decision = onAttemptFailure(policy, this, prospectiveFailedResult(), attemptFailedResult); | ||
| Throwable prospectiveFailedResult = prospectiveFailedResult(); |
There was a problem hiding this comment.
VAKOTODO Use getProspectiveFailedResult().orElse(null).
VAKOTODORun tests onEvergreenand self-review with Claude before asking or review:CrudProseTest.testBulkWriteHandlesCursorRequiringGetMoreWithinTransaction(both sync and async).This PR was originally drafted as stIncMale#4.
client-backpressure.mdandtransactions.mdwas implemented for commands that are read/write retryable.TODO-BACKPRESSUREin the ticket. The audited logic is inSpecRetryPolicy.decideWriteProspectiveFailedResult. We are good, no code changes are needed.