Skip to content

Commit e010f29

Browse files
authored
rename shutdown to terminate and publish it (#2116)
* make waitForPendingWrites public * update tests as well. * Fix CHANGELOG.md * fixing nits. * fix version in changelog * rename shutdown to terminate and publish it * [AUTOMATED]: Prettier Code Styling * addressing document nits
1 parent 4bccd8f commit e010f29

File tree

7 files changed

+89
-68
lines changed

7 files changed

+89
-68
lines changed

packages/firebase/index.d.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6238,6 +6238,28 @@ declare namespace firebase.firestore {
62386238
*/
62396239
waitForPendingWrites(): Promise<void>;
62406240

6241+
/**
6242+
* Terminates this Firestore instance.
6243+
*
6244+
* After calling `terminate()` only the `clearPersistence()` method may be used. Any other method
6245+
* will throw a `FirestoreError`.
6246+
*
6247+
* To restart after termination, create a new instance of FirebaseFirestore with
6248+
* `firebase.firestore()`.
6249+
*
6250+
* Termination does not cancel any pending writes, and any promises that are awaiting a response
6251+
* from the server will not be resolved. If you have persistence enabled, the next time you
6252+
* start this instance, it will resume sending these writes to the server.
6253+
*
6254+
* Note: Under normal circumstances, calling `terminate()` is not required. This
6255+
* method is useful only when you want to force this instance to release all of its resources or
6256+
* in combination with `clearPersistence()` to ensure that all local state is destroyed
6257+
* between test runs.
6258+
*
6259+
* @return A promise that is resolved when the instance has been successfully terminated.
6260+
*/
6261+
terminate(): Promise<void>;
6262+
62416263
/**
62426264
* @hidden
62436265
*/

packages/firestore-types/index.d.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,28 @@ export class FirebaseFirestore {
292292
*/
293293
waitForPendingWrites(): Promise<void>;
294294

295+
/**
296+
* Terminates this Firestore instance.
297+
*
298+
* After calling `terminate()` only the `clearPersistence()` method may be used. Any other method
299+
* will throw a `FirestoreError`.
300+
*
301+
* To restart after termination, create a new instance of FirebaseFirestore with
302+
* `firebase.firestore()`.
303+
*
304+
* Termination does not cancel any pending writes, and any promises that are awaiting a response
305+
* from the server will not be resolved. If you have persistence enabled, the next time you
306+
* start this instance, it will resume sending these writes to the server.
307+
*
308+
* Note: Under normal circumstances, calling `terminate()` is not required. This
309+
* method is useful only when you want to force this instance to release all of its resources or
310+
* in combination with `clearPersistence()` to ensure that all local state is destroyed
311+
* between test runs.
312+
*
313+
* @return A promise that is resolved when the instance has been successfully terminated.
314+
*/
315+
terminate(): Promise<void>;
316+
295317
INTERNAL: { delete: () => Promise<void> };
296318
}
297319

packages/firestore/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
- [feature] Added a `Firestore.waitForPendingWrites()` method that
44
allows users to wait until all pending writes are acknowledged by the
55
Firestore backend.
6+
- [feature] Added a `Firestore.terminate()` method which terminates
7+
the instance, releasing any held resources. Once it completes, you can
8+
optionally call `Firestore.clearPersistence()` to wipe persisted Firestore
9+
data from disk.
610

711
# 1.4.10
812
- [changed] Transactions now perform exponential backoff before retrying.

packages/firestore/src/api/database.ts

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ export class Firestore implements firestore.FirebaseFirestore, FirebaseService {
421421
try {
422422
if (
423423
this._firestoreClient !== undefined &&
424-
!this._firestoreClient.clientShutdown
424+
!this._firestoreClient.clientTerminated
425425
) {
426426
throw new FirestoreError(
427427
Code.FAILED_PRECONDITION,
@@ -437,35 +437,14 @@ export class Firestore implements firestore.FirebaseFirestore, FirebaseService {
437437
return deferred.promise;
438438
}
439439

440-
/**
441-
* Shuts down this Firestore instance.
442-
*
443-
* After shutdown only the `clearPersistence()` method may be used. Any other method
444-
* will throw a `FirestoreError`.
445-
*
446-
* To restart after shutdown, simply create a new instance of FirebaseFirestore with
447-
* `firebase.firestore()`.
448-
*
449-
* Shutdown does not cancel any pending writes and any promises that are awaiting a response
450-
* from the server will not be resolved. If you have persistence enabled, the next time you
451-
* start this instance, it will resume attempting to send these writes to the server.
452-
*
453-
* Note: Under normal circumstances, calling `shutdown()` is not required. This
454-
* method is useful only when you want to force this instance to release all of its resources or
455-
* in combination with `clearPersistence()` to ensure that all local state is destroyed
456-
* between test runs.
457-
*
458-
* @return A promise that is resolved when the instance has been successfully shut down.
459-
*/
460-
// TODO(b/135755126): make this public.
461-
_shutdown(): Promise<void> {
440+
terminate(): Promise<void> {
462441
(this.app as _FirebaseApp)._removeServiceInstance('firestore');
463442
return this.INTERNAL.delete();
464443
}
465444

466-
get _isShutdown(): boolean {
445+
get _isTerminated(): boolean {
467446
this.ensureClientConfigured();
468-
return this._firestoreClient!.clientShutdown;
447+
return this._firestoreClient!.clientTerminated;
469448
}
470449

471450
waitForPendingWrites(): Promise<void> {
@@ -567,7 +546,7 @@ export class Firestore implements firestore.FirebaseFirestore, FirebaseService {
567546
// The client must be initalized to ensure that all subsequent API usage
568547
// throws an exception.
569548
this.ensureClientConfigured();
570-
await this._firestoreClient!.shutdown();
549+
await this._firestoreClient!.terminate();
571550
}
572551
};
573552

packages/firestore/src/core/firestore_client.ts

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ export class FirestoreClient {
162162
* unconditionally resolved.
163163
*/
164164
start(persistenceSettings: InternalPersistenceSettings): Promise<void> {
165-
this.verifyNotShutdown();
165+
this.verifyNotTerminated();
166166
// We defer our initialization until we get the current user from
167167
// setChangeListener(). We block the async queue until we got the initial
168168
// user and the initialization is completed. This will prevent any scheduled
@@ -208,7 +208,7 @@ export class FirestoreClient {
208208

209209
/** Enables the network connection and requeues all pending operations. */
210210
enableNetwork(): Promise<void> {
211-
this.verifyNotShutdown();
211+
this.verifyNotTerminated();
212212
return this.asyncQueue.enqueue(() => {
213213
return this.syncEngine.enableNetwork();
214214
});
@@ -305,14 +305,14 @@ export class FirestoreClient {
305305
}
306306

307307
/**
308-
* Checks that the client has not been shutdown. Ensures that other methods on
309-
* this class cannot be called after the client is shutdown.
308+
* Checks that the client has not been terminated. Ensures that other methods on
309+
* this class cannot be called after the client is terminated.
310310
*/
311-
private verifyNotShutdown(): void {
311+
private verifyNotTerminated(): void {
312312
if (this.asyncQueue.isShuttingDown) {
313313
throw new FirestoreError(
314314
Code.FAILED_PRECONDITION,
315-
'The client has already been shutdown.'
315+
'The client has already been terminated.'
316316
);
317317
}
318318
}
@@ -482,10 +482,10 @@ export class FirestoreClient {
482482
}
483483
});
484484

485-
// When a user calls clearPersistence() in one client, all other clientfs
486-
// need to shut down to allow the delete to succeed.
485+
// When a user calls clearPersistence() in one client, all other clients
486+
// need to be terminated to allow the delete to succeed.
487487
await this.persistence.setDatabaseDeletedListener(async () => {
488-
await this.shutdown();
488+
await this.terminate();
489489
});
490490
});
491491
}
@@ -499,13 +499,13 @@ export class FirestoreClient {
499499

500500
/** Disables the network connection. Pending operations will not complete. */
501501
disableNetwork(): Promise<void> {
502-
this.verifyNotShutdown();
502+
this.verifyNotTerminated();
503503
return this.asyncQueue.enqueue(() => {
504504
return this.syncEngine.disableNetwork();
505505
});
506506
}
507507

508-
shutdown(): Promise<void> {
508+
terminate(): Promise<void> {
509509
return this.asyncQueue.enqueueAndInitiateShutdown(async () => {
510510
// PORTING NOTE: LocalStore does not need an explicit shutdown on web.
511511
if (this.lruScheduler) {
@@ -528,7 +528,7 @@ export class FirestoreClient {
528528
* or rejection.
529529
*/
530530
waitForPendingWrites(): Promise<void> {
531-
this.verifyNotShutdown();
531+
this.verifyNotTerminated();
532532

533533
const deferred = new Deferred<void>();
534534
this.asyncQueue.enqueueAndForget(() => {
@@ -542,7 +542,7 @@ export class FirestoreClient {
542542
observer: Observer<ViewSnapshot>,
543543
options: ListenOptions
544544
): QueryListener {
545-
this.verifyNotShutdown();
545+
this.verifyNotTerminated();
546546
const listener = new QueryListener(query, observer, options);
547547
this.asyncQueue.enqueueAndForget(() => {
548548
return this.eventMgr.listen(listener);
@@ -551,9 +551,9 @@ export class FirestoreClient {
551551
}
552552

553553
unlisten(listener: QueryListener): void {
554-
// Checks for shutdown but does not raise error, allowing unlisten after
555-
// shutdown to be a no-op.
556-
if (this.clientShutdown) {
554+
// Checks for termination but does not raise error, allowing unlisten after
555+
// termination to be a no-op.
556+
if (this.clientTerminated) {
557557
return;
558558
}
559559
this.asyncQueue.enqueueAndForget(() => {
@@ -562,7 +562,7 @@ export class FirestoreClient {
562562
}
563563

564564
getDocumentFromLocalCache(docKey: DocumentKey): Promise<Document | null> {
565-
this.verifyNotShutdown();
565+
this.verifyNotTerminated();
566566
return this.asyncQueue
567567
.enqueue(() => {
568568
return this.localStore.readDocument(docKey);
@@ -585,7 +585,7 @@ export class FirestoreClient {
585585
}
586586

587587
getDocumentsFromLocalCache(query: Query): Promise<ViewSnapshot> {
588-
this.verifyNotShutdown();
588+
this.verifyNotTerminated();
589589
return this.asyncQueue
590590
.enqueue(() => {
591591
return this.localStore.executeQuery(query);
@@ -605,7 +605,7 @@ export class FirestoreClient {
605605
}
606606

607607
write(mutations: Mutation[]): Promise<void> {
608-
this.verifyNotShutdown();
608+
this.verifyNotTerminated();
609609
const deferred = new Deferred<void>();
610610
this.asyncQueue.enqueueAndForget(() =>
611611
this.syncEngine.write(mutations, deferred)
@@ -617,17 +617,17 @@ export class FirestoreClient {
617617
return this.databaseInfo.databaseId;
618618
}
619619

620-
get clientShutdown(): boolean {
620+
get clientTerminated(): boolean {
621621
// Technically, the asyncQueue is still running, but only accepting operations
622-
// related to shutdown or supposed to be run after shutdown. It is effectively
623-
// shut down to the eyes of users.
622+
// related to termination or supposed to be run after termination. It is effectively
623+
// terminated to the eyes of users.
624624
return this.asyncQueue.isShuttingDown;
625625
}
626626

627627
transaction<T>(
628628
updateFunction: (transaction: Transaction) => Promise<T>
629629
): Promise<T> {
630-
this.verifyNotShutdown();
630+
this.verifyNotTerminated();
631631
const deferred = new Deferred<T>();
632632
this.asyncQueue.enqueueAndForget(() => {
633633
this.syncEngine.runTransaction(this.asyncQueue, updateFunction, deferred);

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

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import {
3131
apiDescribe,
3232
arrayContainsAnyOp,
3333
inOp,
34-
shutdownDb,
3534
withTestCollection,
3635
withTestDb,
3736
withTestDbs,
@@ -956,12 +955,12 @@ apiDescribe('Database', (persistence: boolean) => {
956955
});
957956
});
958957

959-
it('rejects subsequent method calls after shutdown() is called', async () => {
958+
it('rejects subsequent method calls after terminate() is called', async () => {
960959
return withTestDb(persistence, db => {
961960
return db.INTERNAL.delete().then(() => {
962961
expect(() => {
963962
db.disableNetwork();
964-
}).to.throw('The client has already been shutdown.');
963+
}).to.throw('The client has already been terminated.');
965964
});
966965
});
967966
});
@@ -1076,7 +1075,7 @@ apiDescribe('Database', (persistence: boolean) => {
10761075
it('can start a new instance after shut down', async () => {
10771076
return withTestDoc(persistence, async docRef => {
10781077
const firestore = docRef.firestore;
1079-
await shutdownDb(firestore);
1078+
await firestore.terminate();
10801079

10811080
const newFirestore = firebase.firestore!(firestore.app);
10821081
expect(newFirestore).to.not.equal(firestore);
@@ -1089,47 +1088,47 @@ apiDescribe('Database', (persistence: boolean) => {
10891088
});
10901089
});
10911090

1092-
it('app delete leads to instance shutdown', async () => {
1091+
it('app delete leads to instance termination', async () => {
10931092
await withTestDoc(persistence, async docRef => {
10941093
await docRef.set({ foo: 'bar' });
10951094
const app = docRef.firestore.app;
10961095
await app.delete();
10971096

10981097
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1099-
expect((docRef.firestore as any)._isShutdown).to.be.true;
1098+
expect((docRef.firestore as any)._isTerminated).to.be.true;
11001099
});
11011100
});
11021101

1103-
it('new operation after shutdown should throw', async () => {
1102+
it('new operation after termination should throw', async () => {
11041103
await withTestDoc(persistence, async docRef => {
11051104
const firestore = docRef.firestore;
1106-
await shutdownDb(firestore);
1105+
await firestore.terminate();
11071106

11081107
expect(() => {
11091108
firestore.doc(docRef.path).set({ foo: 'bar' });
1110-
}).to.throw();
1109+
}).to.throw('The client has already been terminated.');
11111110
});
11121111
});
11131112

1114-
it('calling shutdown mutiple times should proceed', async () => {
1113+
it('calling terminate mutiple times should proceed', async () => {
11151114
await withTestDoc(persistence, async docRef => {
11161115
const firestore = docRef.firestore;
1117-
await shutdownDb(firestore);
1118-
await shutdownDb(firestore);
1116+
await firestore.terminate();
1117+
await firestore.terminate();
11191118

11201119
expect(() => {
11211120
firestore.doc(docRef.path).set({ foo: 'bar' });
11221121
}).to.throw();
11231122
});
11241123
});
11251124

1126-
it('can unlisten queries after shutdown', async () => {
1125+
it('can unlisten queries after termination', async () => {
11271126
return withTestDoc(persistence, async docRef => {
11281127
const firestore = docRef.firestore;
11291128
const accumulator = new EventsAccumulator<firestore.DocumentSnapshot>();
11301129
const unsubscribe = docRef.onSnapshot(accumulator.storeEvent);
11311130
await accumulator.awaitEvent();
1132-
await shutdownDb(firestore);
1131+
await firestore.terminate();
11331132

11341133
// This should proceed without error.
11351134
unsubscribe();

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -358,11 +358,6 @@ function wipeDb(db: firestore.FirebaseFirestore): Promise<void> {
358358
return Promise.resolve(undefined);
359359
}
360360

361-
export function shutdownDb(db: firestore.FirebaseFirestore): Promise<void> {
362-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
363-
return (db as any)._shutdown();
364-
}
365-
366361
// TODO(in-queries): This exists just so we don't have to do the cast
367362
// repeatedly. Once we expose 'array-contains-any' publicly we can remove it and
368363
// just use 'array-contains-any' in all the tests.

0 commit comments

Comments
 (0)