Skip to content

Commit 0668f2a

Browse files
refactor loop
1 parent 5f6825d commit 0668f2a

File tree

1 file changed

+34
-22
lines changed

1 file changed

+34
-22
lines changed

src/sessions.ts

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -735,8 +735,35 @@ export class ClientSession
735735
let committed = false;
736736
let result: T;
737737

738+
let lastError: Error | null = null;
739+
738740
try {
739-
for (let retry = 0; !committed; ++retry) {
741+
retryTransaction: for (let attempt = 0, isRetry = attempt > 0; !committed; ++attempt) {
742+
if (isRetry) {
743+
const BACKOFF_INITIAL_MS = 5;
744+
const BACKOFF_MAX_MS = 500;
745+
const BACKOFF_GROWTH = 1.5;
746+
const jitter = Math.random();
747+
const backoffMS =
748+
jitter * Math.min(BACKOFF_INITIAL_MS * BACKOFF_GROWTH ** attempt, BACKOFF_MAX_MS);
749+
750+
const willExceedTransactionDeadline =
751+
(this.timeoutContext?.csotEnabled() &&
752+
backoffMS > this.timeoutContext.remainingTimeMS) ||
753+
processTimeMS() + backoffMS > startTime + MAX_TIMEOUT;
754+
755+
if (willExceedTransactionDeadline) {
756+
throw (
757+
lastError ??
758+
new MongoRuntimeError(
759+
`Transaction retry did not record an error: should never occur. Please file a bug.`
760+
)
761+
);
762+
}
763+
764+
await setTimeout(backoffMS);
765+
}
766+
740767
this.startTransaction(options); // may throw on error
741768

742769
try {
@@ -774,13 +801,14 @@ export class ClientSession
774801
fnError.hasErrorLabel(MongoErrorLabel.TransientTransactionError) &&
775802
(this.timeoutContext?.csotEnabled() || processTimeMS() - startTime < MAX_TIMEOUT)
776803
) {
777-
continue;
804+
lastError = fnError;
805+
continue retryTransaction;
778806
}
779807

780808
throw fnError;
781809
}
782810

783-
while (!committed) {
811+
retryCommit: while (!committed) {
784812
try {
785813
/*
786814
* We will rely on ClientSession.commitTransaction() to
@@ -809,29 +837,13 @@ export class ClientSession
809837
* { ok:0, code: 50, codeName: 'MaxTimeMSExpired' }
810838
* { ok:1, writeConcernError: { code: 50, codeName: 'MaxTimeMSExpired' } }
811839
*/
812-
continue;
840+
continue retryCommit;
813841
}
814842

815843
if (commitError.hasErrorLabel(MongoErrorLabel.TransientTransactionError)) {
816-
const BACKOFF_INITIAL_MS = 5;
817-
const BACKOFF_MAX_MS = 500;
818-
const BACKOFF_GROWTH = 1.5;
819-
const jitter = Math.random();
820-
const backoffMS =
821-
jitter * Math.min(BACKOFF_INITIAL_MS * BACKOFF_GROWTH ** retry, BACKOFF_MAX_MS);
822-
823-
const willExceedTransactionDeadline =
824-
(this.timeoutContext?.csotEnabled() &&
825-
backoffMS > this.timeoutContext.remainingTimeMS) ||
826-
processTimeMS() + backoffMS > startTime + MAX_TIMEOUT;
827-
828-
if (willExceedTransactionDeadline) {
829-
break;
830-
}
831-
832-
await setTimeout(backoffMS);
844+
lastError = commitError;
833845

834-
break;
846+
continue retryTransaction;
835847
}
836848
}
837849

0 commit comments

Comments
 (0)