Skip to content

Commit 614b1d7

Browse files
Feedback
1 parent 2187e60 commit 614b1d7

File tree

2 files changed

+23
-15
lines changed

2 files changed

+23
-15
lines changed

packages/firestore/src/util/async_queue.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ export class AsyncQueue {
207207
// The last promise in the queue.
208208
private tail: Promise<unknown> = Promise.resolve();
209209

210-
// A list of retryable operations Retryable operation are run in order and
210+
// A list of retryable operations. Retryable operations are run in order and
211211
// retried with backoff.
212212
private retryableOps: Array<() => Promise<void>> = [];
213213

@@ -332,21 +332,29 @@ export class AsyncQueue {
332332
* reschedules with backoff.
333333
*/
334334
private async retryNextOp(): Promise<void> {
335-
const op = this.retryableOps.shift();
336-
337-
if (op) {
338-
try {
339-
await op();
340-
this.backoff.reset();
341-
} catch (e) {
342-
if (isIndexedDbTransactionError(e)) {
343-
logDebug(LOG_TAG, 'Operation failed with retryable error: ' + e);
344-
this.retryableOps.unshift(op);
345-
} else {
346-
throw e; // Failure will be handled by AsyncQueue
347-
}
335+
if (this.retryableOps.length === 0) {
336+
return;
337+
}
338+
339+
try {
340+
await this.retryableOps[0]();
341+
this.retryableOps.shift();
342+
this.backoff.reset();
343+
} catch (e) {
344+
if (isIndexedDbTransactionError(e)) {
345+
logDebug(LOG_TAG, 'Operation failed with retryable error: ' + e);
346+
} else {
347+
throw e; // Failure will be handled by AsyncQueue
348348
}
349+
}
349350

351+
if (this.retryableOps.length > 0) {
352+
// Note: This might schedule a `retryNextOp()` even though the items in
353+
// the queue may have already been enqueued. Since `backoffAndRun()`
354+
// cancels an existing backoff and schedules a new backoff on every call,
355+
// there is only ever a single additional operation in the queue. This
356+
// operation can then run retryable operations that failed during their
357+
// initial attempt.
350358
this.backoff.backoffAndRun(() => this.retryNextOp());
351359
}
352360
}

packages/firestore/test/unit/util/async_queue.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ describe('AsyncQueue', () => {
312312
expect(completedSteps).to.deep.equal([1, 1, 2]);
313313
});
314314

315-
it('Doesn not delay retryable operations that succeed', async () => {
315+
it('Does not delay retryable operations that succeed', async () => {
316316
const queue = new AsyncQueue();
317317
const completedSteps: number[] = [];
318318
const doStep = (n: number): void => {

0 commit comments

Comments
 (0)