-
Notifications
You must be signed in to change notification settings - Fork 617
Prepare shutdown
to be a public api.
#589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
fa5e624
9ba6ff3
835ddc8
e7e3ea1
317fea7
34171e8
74d507c
fe02b17
f8b33ed
d3141b2
701fcef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -117,7 +117,13 @@ static FirebaseFirestore newInstance( | |
// so there is no need to include it in the persistence key. | ||
String persistenceKey = app.getName(); | ||
|
||
return new FirebaseFirestore(context, databaseId, persistenceKey, provider, queue, app); | ||
FirebaseFirestore firestore = | ||
new FirebaseFirestore(context, databaseId, persistenceKey, provider, queue, app); | ||
app.addLifecycleEventListener( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the wrong layer at which to do this. Instead, have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
/* onDeleted */ (firebaseAppName, options) -> { | ||
firestore.shutdown(/* fromAppDeletion */ true); | ||
wilhuff marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
return firestore; | ||
} | ||
|
||
@VisibleForTesting | ||
|
@@ -329,13 +335,43 @@ public Task<Void> runBatch(@NonNull WriteBatch.Function batchFunction) { | |
return batch.commit(); | ||
} | ||
|
||
@VisibleForTesting | ||
Task<Void> shutdown() { | ||
Task<Void> shutdown(boolean fromAppDeletion) { | ||
if (!fromAppDeletion && this.getApp() != null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be clearer if we split this apart:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
FirestoreMultiDbComponent component = this.getApp().get(FirestoreMultiDbComponent.class); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should not modify the errorprone check for "convenience" as this convenience comes at a price:
That said, I'd recommend something along the following lines:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Basically what you suggested, slight tweak. |
||
component.remove(this.databaseId.getDatabaseId()); | ||
} | ||
// The client must be initialized to ensure that all subsequent API usage throws an exception. | ||
this.ensureClientConfigured(); | ||
return client.shutdown(); | ||
} | ||
|
||
/** | ||
* Shuts down this Firestore SDK instance. | ||
wilhuff marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* | ||
* <p>IMPORTANT: If your application is designed to run with Firestore the entire life cycle, it | ||
* is not recommended to call `shutdown` explicitly, the shutting down happens naturally when the | ||
* application itself is shut down. | ||
* | ||
* <p>For applications designed to run without Firestore from some point on (typically to save | ||
* resources as much as possible), you may call this method. | ||
* | ||
* <p>Once `shutdown` is called, trying to issue new reads/writes through this instance will | ||
* result in {@link IllegalStateException}. Already requested reads/writes might stop resolving. | ||
* Be sure to handle this well in your application if proceeding with Firestore shutting down is | ||
* desired in your case. | ||
* | ||
* <p>Note that {@link #clearPersistence()} is an exception, it is designed to run when the | ||
* Firestore SDK instance is shutdown. | ||
* | ||
* <p>To re-start a Firestore SDK instance, simply create a new instance via {@link | ||
* #getInstance()} or {@link #getInstance(FirebaseApp)}. | ||
*/ | ||
@VisibleForTesting | ||
// TODO: Make this public and remove @VisibleForTesting | ||
wilhuff marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Task<Void> shutdown() { | ||
return shutdown(/* fromAppDeletion */ false); | ||
wilhuff marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
@VisibleForTesting | ||
AsyncQueue getAsyncQueue() { | ||
return asyncQueue; | ||
|
@@ -396,7 +432,7 @@ public static void setLoggingEnabled(boolean loggingEnabled) { | |
@PublicApi | ||
public Task<Void> clearPersistence() { | ||
final TaskCompletionSource<Void> source = new TaskCompletionSource<>(); | ||
asyncQueue.enqueueAndForget( | ||
asyncQueue.enqueueAndForgetEvenAfterShutdown( | ||
() -> { | ||
try { | ||
if (client != null && !client.isShutdown()) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,7 +75,6 @@ public final class FirestoreClient implements RemoteStore.RemoteStoreCallback { | |
private RemoteStore remoteStore; | ||
private SyncEngine syncEngine; | ||
private EventManager eventManager; | ||
private volatile boolean clientShutdown = false; | ||
|
||
// LRU-related | ||
@Nullable private LruGarbageCollector.Scheduler lruScheduler; | ||
|
@@ -138,21 +137,21 @@ public Task<Void> enableNetwork() { | |
/** Shuts down this client, cancels all writes / listeners, and releases all resources. */ | ||
public Task<Void> shutdown() { | ||
credentialsProvider.removeChangeListener(); | ||
return asyncQueue.enqueue( | ||
return asyncQueue.enqueueAndInitiateShutdown( | ||
() -> { | ||
if (!this.clientShutdown) { | ||
remoteStore.shutdown(); | ||
persistence.shutdown(); | ||
if (lruScheduler != null) { | ||
lruScheduler.stop(); | ||
} | ||
this.clientShutdown = true; | ||
remoteStore.shutdown(); | ||
persistence.shutdown(); | ||
if (lruScheduler != null) { | ||
lruScheduler.stop(); | ||
} | ||
}); | ||
} | ||
|
||
/** Has this client been shutdown. */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use a verb phrase that describes what the method does as if the sentence starts with "This method" (see http://go/java-practices/javadoc#summary_methods). e.g. /** Returns true if this client has been shut down. */ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
public boolean isShutdown() { | ||
return this.clientShutdown; | ||
// Technically, the asyncQueue is still running, but only accepting tasks related to shutdown | ||
// or supposed to be run after shutdown. It is effectively shut down to the eyes of users. | ||
return this.asyncQueue.isShuttingDown(); | ||
} | ||
|
||
/** Starts listening to a query. */ | ||
|
@@ -272,8 +271,8 @@ private void initialize(Context context, User user, boolean usePersistence, long | |
} | ||
|
||
private void verifyNotShutdown() { | ||
if (this.clientShutdown) { | ||
throw new IllegalArgumentException("The client has already been shutdown"); | ||
if (this.isShutdown()) { | ||
throw new IllegalStateException("The client has already been shutdown"); | ||
} | ||
} | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.