Skip to content

Commit 2715154

Browse files
committed
addressing comments
1 parent 5897991 commit 2715154

File tree

6 files changed

+36
-51
lines changed

6 files changed

+36
-51
lines changed

packages/firestore/src/api/database.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ export class Firestore implements firestore.FirebaseFirestore, FirebaseService {
482482
* Waits until all currently pending writes for the active user have been acknowledged by the
483483
* backend.
484484
*
485-
* The returned Promise completes immediately if there are no outstanding writes. Otherwise, the
485+
* The returned Promise resolves immediately if there are no outstanding writes. Otherwise, the
486486
* Task waits for all previously issued writes (including those written in a previous app
487487
* session), but it does not wait for writes that were added after the method is called. If you
488488
* wish to wait for additional writes, you have to call `waitForPendingWrites()` again.
@@ -493,6 +493,7 @@ export class Firestore implements firestore.FirebaseFirestore, FirebaseService {
493493
* acknowledged by the backend.
494494
*/
495495
_waitForPendingWrites(): Promise<void> {
496+
this.ensureClientConfigured();
496497
return this._firestoreClient!.waitForPendingWrites();
497498
}
498499

packages/firestore/src/core/firestore_client.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -523,8 +523,9 @@ export class FirestoreClient {
523523
}
524524

525525
/**
526-
* Returns a `Promise` resolves when all the pending writes at the time when this method is called
527-
* received server acknowledgement. An acknowledgement can be either acceptance or rejections.
526+
* Returns a Promise that resolves when when all writes that were pending at the time when this
527+
* method is called received server acknowledgement. An acknowledgement can be either acceptance
528+
* or rejections.
528529
*/
529530
waitForPendingWrites(): Promise<void> {
530531
this.verifyNotShutdown();
@@ -550,6 +551,7 @@ export class FirestoreClient {
550551
}
551552

552553
unlisten(listener: QueryListener): void {
554+
this.verifyNotShutdown();
553555
this.asyncQueue.enqueueAndForget(() => {
554556
return this.eventMgr.unlisten(listener);
555557
});

packages/firestore/src/core/sync_engine.ts

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -610,9 +610,9 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
610610
}
611611

612612
/**
613-
* Takes a snapshot of current mutation queue, and register a user callback
614-
* which will be called when all those mutations in the snapshot are either
615-
* accepted or rejected by the server.
613+
* Registers a user callback with all the pending mutations at the moment of calling.
614+
* When all those mutations are either accepted or rejected by the server, the
615+
* registered callback will be triggered.
616616
*/
617617
async registerPendingWritesCallback(callback: Deferred<void>): Promise<void> {
618618
if (!this.remoteStore.canUseNetwork()) {
@@ -623,22 +623,20 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
623623
);
624624
}
625625

626-
const largestBatchId = await this.localStore.getHighestUnacknowledgedBatchId();
627-
628-
if (largestBatchId === BATCHID_UNKNOWN) {
626+
const highestBatchId = await this.localStore.getHighestUnacknowledgedBatchId();
627+
if (highestBatchId === BATCHID_UNKNOWN) {
629628
// Trigger the callback right away if there is no pending writes at the moment.
630629
callback.resolve();
631-
return Promise.resolve();
630+
return;
632631
}
633632

634-
const callbacks = this.pendingWritesCallbacks.get(largestBatchId) || [];
633+
const callbacks = this.pendingWritesCallbacks.get(highestBatchId) || [];
635634
callbacks.push(callback);
636-
this.pendingWritesCallbacks.set(largestBatchId, callbacks);
637-
return Promise.resolve();
635+
this.pendingWritesCallbacks.set(highestBatchId, callbacks);
638636
}
639637

640638
/**
641-
* Triggers callbacks waiting for this batch id to get acknowledged by server,
639+
* Triggers the callbacks that are waiting for this batch id to get acknowledged by server,
642640
* if there are any.
643641
*/
644642
private triggerPendingWritesCallbacks(batchId: BatchId): void {
@@ -650,13 +648,12 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
650648
}
651649

652650
/** Reject all outstanding callbacks waiting for pending writes to complete. */
653-
private rejectOutstandingPendingWritesCallbacks(): void {
651+
private rejectOutstandingPendingWritesCallbacks(errorMessage: string): void {
654652
this.pendingWritesCallbacks.forEach(callbacks => {
655653
callbacks.forEach(callback => {
656654
callback.reject(
657655
new FirestoreError(
658-
Code.CANCELLED,
659-
"'waitForPendingWrites' task is cancelled due to User change."
656+
Code.CANCELLED, errorMessage
660657
)
661658
);
662659
});
@@ -863,7 +860,9 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
863860

864861
if (userChanged) {
865862
// Fails tasks waiting for pending writes requested by previous user.
866-
this.rejectOutstandingPendingWritesCallbacks();
863+
this.rejectOutstandingPendingWritesCallbacks(
864+
"'waitForPendingWrites' promise is rejected due to a user change."
865+
);
867866

868867
const result = await this.localStore.handleUserChange(user);
869868
// TODO(b/114226417): Consider calling this only in the primary tab.

packages/firestore/src/local/indexeddb_mutation_queue.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,7 @@ export class IndexedDbMutationQueue implements MutationQueue {
268268
getHighestUnacknowledgedBatchId(
269269
transaction: PersistenceTransaction
270270
): PersistencePromise<BatchId> {
271-
const range = IDBKeyRange.bound(
272-
[this.userId, Number.NEGATIVE_INFINITY],
271+
const range = IDBKeyRange.upperBound(
273272
[this.userId, Number.POSITIVE_INFINITY]
274273
);
275274

packages/firestore/test/integration/api/database.test.ts

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,21 +1101,6 @@ apiDescribe('Database', (persistence: boolean) => {
11011101
});
11021102
});
11031103

1104-
it('can unlisten queries after shutdown', async () => {
1105-
return withTestDoc(persistence, async docRef => {
1106-
const firestore = docRef.firestore;
1107-
const accumulator = new EventsAccumulator<firestore.DocumentSnapshot>();
1108-
const unsubscribe = docRef.onSnapshot(accumulator.storeEvent);
1109-
await accumulator.awaitEvent();
1110-
await shutdownDb(firestore);
1111-
1112-
// This should proceed without error.
1113-
unsubscribe();
1114-
// Multiple calls should proceed as well.
1115-
unsubscribe();
1116-
});
1117-
});
1118-
11191104
it('new operation after shutdown should throw', async () => {
11201105
await withTestDoc(persistence, async docRef => {
11211106
const firestore = docRef.firestore;
@@ -1139,24 +1124,19 @@ apiDescribe('Database', (persistence: boolean) => {
11391124
});
11401125
});
11411126

1142-
it('can wait for pending writes as expected', async () => {
1127+
it('can wait for pending writes', async () => {
11431128
await withTestDoc(persistence, async docRef => {
11441129
const firestore = docRef.firestore;
11451130
// Prevent pending writes receiving acknowledgement.
11461131
await firestore.disableNetwork();
11471132

1148-
const awaitPendingWrites1 = waitForPendingWrites(firestore);
11491133
const pendingWrites = docRef.set({ foo: 'bar' });
1150-
const awaitPendingWrites2 = waitForPendingWrites(firestore);
1151-
1152-
// `awaitsPendingWrites1` resolves immediately because there are no pending writes at
1153-
// the time it is created.
1154-
await expect(awaitPendingWrites1).to.be.eventually.fulfilled;
1134+
const awaitPendingWrites = waitForPendingWrites(firestore);
11551135

11561136
// pending writes can receive acknowledgements now.
11571137
await firestore.enableNetwork();
1158-
await expect(pendingWrites).to.be.eventually.fulfilled;
1159-
await expect(awaitPendingWrites2).to.be.eventually.fulfilled;
1138+
await pendingWrites;
1139+
await awaitPendingWrites;
11601140
});
11611141
});
11621142

@@ -1167,9 +1147,11 @@ apiDescribe('Database', (persistence: boolean) => {
11671147
db.doc('abc/123').set({ foo: 'bar' });
11681148
const awaitPendingWrite = waitForPendingWrites(db);
11691149

1170-
mockCredentialsProvider.changeUserTo(new User('user_1'));
1150+
mockCredentialsProvider.triggerUserChange(new User('user_1'));
11711151

1172-
await expect(awaitPendingWrite).to.be.eventually.rejected;
1152+
await expect(awaitPendingWrite).to.be.eventually.rejectedWith(
1153+
"'waitForPendingWrites' promise is rejected due to a user change."
1154+
);
11731155
});
11741156
});
11751157

@@ -1180,8 +1162,10 @@ apiDescribe('Database', (persistence: boolean) => {
11801162
// Prevent pending writes receiving acknowledgement.
11811163
await firestore.disableNetwork();
11821164

1165+
// `awaitsPendingWrites` is created when there is no pending writes, it will resolve
1166+
// immediately even if we are offline.
11831167
const awaitPendingWrites = waitForPendingWrites(firestore);
1184-
await expect(awaitPendingWrites).to.be.eventually.fulfilled;
1168+
await awaitPendingWrites;
11851169
});
11861170
});
11871171
});

packages/firestore/test/integration/util/helpers.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ export class MockCredentialsProvider extends EmptyCredentialsProvider {
130130

131131
private listener: CredentialChangeListener | null = null;
132132

133-
changeUserTo(user: User): void {
134-
this.listener!(user);
133+
triggerUserChange(newUser: User): void {
134+
this.listener!(newUser);
135135
}
136136

137137
setChangeListener(listener: CredentialChangeListener): void {
@@ -185,8 +185,8 @@ export function withMockCredentialProviderTestDb(
185185
): Promise<void> {
186186
const mockCredentialsProvider = new MockCredentialsProvider();
187187
// eslint-disable-next-line @typescript-eslint/no-explicit-any
188-
const settings: any = { ...DEFAULT_SETTINGS };
189-
settings.credentials = { client: mockCredentialsProvider, type: 'provider' };
188+
const settings = {... DEFAULT_SETTINGS,
189+
credentials: { client: mockCredentialsProvider, type: 'provider' }};
190190
return withTestDbsSettings(persistence, DEFAULT_PROJECT_ID, settings, 1,
191191
([db]) => {
192192
return fn(db, mockCredentialsProvider);

0 commit comments

Comments
 (0)