-
Notifications
You must be signed in to change notification settings - Fork 938
Bundles load from secondary tabs #3393
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
Conversation
# Conflicts: # packages/firestore/src/util/bundle_reader.ts # packages/firestore/test/unit/util/bundle.test.ts
# Conflicts: # packages/firestore/src/util/bundle_reader.ts # packages/firestore/test/unit/util/bundle.test.ts
Fix change buffer bug
Two TODO: 1. load from secondary tab. 2. don't fail async queue.
💥 No ChangesetLatest commit: 5a4d0f2 Merging this PR will not cause any packages to be released. If these changes should not cause updates to packages in this repo, this is fine 🙂 If these changes should be published to npm, you need to add a changeset. This PR includes no changesetsWhen changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types Click here to learn what changesets are, and how to add one. Click here if you're a maintainer who wants to add a changeset to this PR |
# Conflicts: # integration/messaging/test/utils/openNewTab.js # packages/firestore-types/index.d.ts # packages/firestore/src/core/bundle.ts # packages/firestore/src/core/component_provider.ts # packages/firestore/src/core/firestore_client.ts # packages/firestore/src/core/sync_engine.ts # packages/firestore/src/local/bundle_cache.ts # packages/firestore/src/local/indexeddb_bundle_cache.ts # packages/firestore/src/local/indexeddb_persistence.ts # packages/firestore/src/local/indexeddb_remote_document_cache.ts # packages/firestore/src/local/local_serializer.ts # packages/firestore/src/local/local_store.ts # packages/firestore/src/local/memory_bundle_cache.ts # packages/firestore/src/local/memory_remote_document_cache.ts # packages/firestore/src/local/remote_document_change_buffer.ts # packages/firestore/src/platform/platform.ts # packages/firestore/src/platform_browser/browser_platform.ts # packages/firestore/src/platform_node/node_platform.ts # packages/firestore/src/remote/serializer.ts # packages/firestore/src/util/bundle_reader.ts # packages/firestore/test/unit/local/bundle_cache.test.ts # packages/firestore/test/unit/local/local_store.test.ts # packages/firestore/test/unit/local/persistence_test_helpers.ts # packages/firestore/test/unit/local/test_bundle_cache.ts # packages/firestore/test/unit/specs/bundle_spec.test.ts # packages/firestore/test/unit/specs/spec_test_components.ts # packages/firestore/test/unit/specs/spec_test_runner.ts # packages/firestore/test/unit/util/bundle.test.ts # packages/firestore/test/util/helpers.ts # packages/firestore/test/util/test_platform.ts
Binary Size ReportAffected SDKs
Test Logs |
async synchronizeWithChangedDocuments(): Promise<void> { | ||
const changes = await this.localStore.getNewDocumentChanges(); | ||
await this.emitNewSnapsAndNotifyLocalStore(changes); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the style of method where I would advocate to drop the await keyword and simply return the Promise. See here for the code overhead of using await
in ES5: https://www.typescriptlang.org/play/?target=1#code/IYZwngdgxgBAZgV2gFwJYHsL3egFAShgG8AoGcmYAd2FWRggFMqYAFAJ3QFtURHcCMALwA+YgF98AbhLigA
Note that __awaiter and __generator are already part of our code base, so we are only looking at the overhead in foo
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks for the explaination.
/** | ||
* An instance of the Platform's 'TextEncoder' implementation. | ||
*/ | ||
export function newTextEncoder(): TextEncoder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only be in platform is there is some divergence between platforms. This doesn't seem to be the case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yarn test:node
complains there is no TextEncoder
, it looks like it has to be imported from util
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sad :/
Should we move this to the ./serializer.ts file though? It seems much more fitting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, but it is not used in serializer.ts
. The only place it is used in non-testing code is util/bundle_reader.ts
, I think it makes slightly more sense to keep it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean to move it from packages/firestore/src/platform/browser/dom.ts to packages/firestore/src/platform/browser/serializer.ts. It has little to do with DOM, mostly because it exists in Node which doesn't have DOM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, sorry. Done.
// The WebStorage prefix that plays as a event to indicate the remote documents | ||
// might have changed due to some actions secondary tabs did. | ||
// format of the key is: | ||
// firestore_remote_documents_changed_<persistence_prefix> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// firestore_remote_documents_changed_<persistence_prefix> | |
// firestore_remote_documents_changed_<persistenceKey> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
// format of the key is: | ||
// firestore_remote_documents_changed_<persistence_prefix> | ||
export const REMOTE_DOCUMENTS_CHANGED_KEY_PREFIX = | ||
'firestore_remote_documents_changed'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the remote documents change when queries get updated and even when mutations are committed, but this even only fires when a bundle is loaded. Should this be a bundle specific notification?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also update the key prefix. For sake of brevity, you could consider dropping "remote documents" altogether and just make it something like "bundle loaded".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -711,6 +719,10 @@ export class WebStorageSharedClientState implements SharedClientState { | |||
this.persistOnlineState(onlineState); | |||
} | |||
|
|||
remoteDocumentsChanged(): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
notifyRemoteDocumentsChanged()
? But also see my comment below: I think this should be bundle specific.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -1412,7 +1417,11 @@ export function loadBundle( | |||
syncEngineImpl.assertSubscribed('loadBundle()'); | |||
|
|||
// eslint-disable-next-line @typescript-eslint/no-floating-promises | |||
loadBundleImpl(syncEngineImpl, bundleReader, task); | |||
loadBundleImpl(syncEngineImpl, bundleReader, task).then(() => { | |||
if (!syncEngineImpl.isPrimaryClient) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a downside to invoking this on all tabs? Seems like we should issue this notification even on the primary tabs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, this can be called on all tabs.
@@ -173,6 +174,8 @@ export interface SharedClientState { | |||
setOnlineState(onlineState: OnlineState): void; | |||
|
|||
writeSequenceNumber(sequenceNumber: ListenSequenceNumber): void; | |||
|
|||
remoteDocumentsChanged(): void; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add JSDoc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -49,4 +49,10 @@ export interface SharedClientStateSyncer { | |||
|
|||
/** Returns the IDs of the clients that are currently active. */ | |||
getActiveClients(): Promise<ClientId[]>; | |||
|
|||
/** | |||
* Query for changed documents from remote document cache and raise snapshots |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Query for changed documents from remote document cache and raise snapshots | |
* Retrieves newly changed documents from remote document cache and raises snapshots |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -41,3 +41,30 @@ export function getDocument(): Document | null { | |||
return browser.getDocument(); | |||
} | |||
} | |||
|
|||
/** | |||
* An instance of the Platform's 'TextEncoder' implementation or null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This never returns null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
// format of the key is: | ||
// firestore_remote_documents_changed_<persistence_prefix> | ||
export const REMOTE_DOCUMENTS_CHANGED_KEY_PREFIX = | ||
'firestore_remote_documents_changed'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also update the key prefix. For sake of brevity, you could consider dropping "remote documents" altogether and just make it something like "bundle loaded".
/** | ||
* An instance of the Platform's 'TextEncoder' implementation. | ||
*/ | ||
export function newTextEncoder(): TextEncoder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sad :/
Should we move this to the ./serializer.ts file though? It seems much more fitting.
@@ -77,6 +78,8 @@ export class BundleReader { | |||
/** The reader to read from underlying binary bundle data source. */ | |||
private reader: ReadableStreamReader<Uint8Array> | |||
) { | |||
this.textDecoder = newTextDecoder(); | |||
debugAssert(!!this.textDecoder, 'Cannot create a valid text decoder.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would never fire, would it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, fixed.
@@ -131,7 +134,7 @@ export class BundleReader { | |||
return null; | |||
} | |||
|
|||
const lengthString = this.textDecoder.decode(lengthBuffer); | |||
const lengthString = this.textDecoder!.decode(lengthBuffer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop bang.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -199,7 +202,7 @@ export class BundleReader { | |||
} | |||
} | |||
|
|||
const result = this.textDecoder.decode(this.buffer.slice(0, length)); | |||
const result = this.textDecoder!.decode(this.buffer.slice(0, length)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop bang.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -532,6 +540,10 @@ export class WebStorageSharedClientState implements SharedClientState { | |||
|
|||
this.onlineStateKey = createWebStorageOnlineStateKey(this.persistenceKey); | |||
|
|||
this.bundleChangedRemoteDocumentsKey = createRemoteDocumentsLoadFromBundleKey( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createRemoteDocumentsLoadFromBundleKey
seems like it needs a name update now as well. createBundleLoadedKey
?
For sake of brevity, I would also change bundleChangedRemoteDocumentsKey to bundleLoadedKey. I seems shorter and more specific.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
/** | ||
* An instance of the Platform's 'TextEncoder' implementation. | ||
*/ | ||
export function newTextEncoder(): TextEncoder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean to move it from packages/firestore/src/platform/browser/dom.ts to packages/firestore/src/platform/browser/serializer.ts. It has little to do with DOM, mostly because it exists in Node which doesn't have DOM.
Hey there! So you want to contribute to a Firebase SDK?
Before you file this pull request, please read these guidelines:
Discussion
If not, go file an issue about this before creating a pull request to discuss.
Testing
API Changes
us make Firebase APIs better, please propose your change in an issue so that we
can discuss it together.