Skip to content

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

Merged
merged 34 commits into from
Jul 23, 2020
Merged

Conversation

wu-hui
Copy link
Contributor

@wu-hui wu-hui commented Jul 11, 2020

Hey there! So you want to contribute to a Firebase SDK?
Before you file this pull request, please read these guidelines:

Discussion

  • Read the contribution guidelines (CONTRIBUTING.md).
  • If this has been discussed in an issue, make sure to link to the issue here.
    If not, go file an issue about this before creating a pull request to discuss.

Testing

  • Make sure all existing tests in the repository pass after your change.
  • If you fixed a bug or added a feature, add a new test to cover your code.

API Changes

  • At this time we cannot accept changes that affect the public API. If you'd like to help
    us make Firebase APIs better, please propose your change in an issue so that we
    can discuss it together.

wu-hui added 30 commits May 21, 2020 13:49
# 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
Two TODO:
1. load from secondary tab.
2. don't fail async queue.
@changeset-bot
Copy link

changeset-bot bot commented Jul 11, 2020

💥 No Changeset

Latest 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 changesets

When 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
@google-oss-bot
Copy link
Contributor

google-oss-bot commented Jul 11, 2020

Binary Size Report

Affected SDKs

  • @firebase/firestore

    Type Base (2bfa185) Head (0c062c6) Diff
    browser 258 kB 258 kB +384 B (+0.1%)
    esm2017 201 kB 201 kB +254 B (+0.1%)
    main 514 kB 515 kB +1.02 kB (+0.2%)
    module 255 kB 255 kB +384 B (+0.2%)
    react-native 201 kB 201 kB +254 B (+0.1%)
  • @firebase/firestore/exp

    Type Base (2bfa185) Head (0c062c6) Diff
    main 415 kB 416 kB +812 B (+0.2%)
  • @firebase/firestore/memory

    Type Base (2bfa185) Head (0c062c6) Diff
    browser 195 kB 195 kB +61 B (+0.0%)
    esm2017 153 kB 153 kB +28 B (+0.0%)
    main 384 kB 384 kB +248 B (+0.1%)
    module 193 kB 193 kB +61 B (+0.0%)
    react-native 153 kB 153 kB +28 B (+0.0%)
  • firebase

    Type Base (2bfa185) Head (0c062c6) Diff
    firebase-firestore.js 295 kB 295 kB +362 B (+0.1%)
    firebase-firestore.memory.js 235 kB 235 kB +60 B (+0.0%)
    firebase.js 829 kB 829 kB +362 B (+0.0%)

Test Logs

Comment on lines 1103 to 1106
async synchronizeWithChangedDocuments(): Promise<void> {
const changes = await this.localStore.getNewDocumentChanges();
await this.emitNewSnapsAndNotifyLocalStore(changes);
}
Copy link
Contributor

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.

Copy link
Contributor Author

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 {
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// firestore_remote_documents_changed_<persistence_prefix>
// firestore_remote_documents_changed_<persistenceKey>

Copy link
Contributor Author

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';
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor

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".

Copy link
Contributor Author

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 {
Copy link
Contributor

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.

Copy link
Contributor Author

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) {
Copy link
Contributor

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.

Copy link
Contributor Author

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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add JSDoc.

Copy link
Contributor Author

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Query for changed documents from remote document cache and raise snapshots
* Retrieves newly changed documents from remote document cache and raises snapshots

Copy link
Contributor Author

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This never returns null.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@wu-hui wu-hui assigned schmidt-sebastian and unassigned wu-hui Jul 22, 2020
// format of the key is:
// firestore_remote_documents_changed_<persistence_prefix>
export const REMOTE_DOCUMENTS_CHANGED_KEY_PREFIX =
'firestore_remote_documents_changed';
Copy link
Contributor

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 {
Copy link
Contributor

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.');
Copy link
Contributor

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?

Copy link
Contributor Author

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop bang.

Copy link
Contributor Author

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));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop bang.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@wu-hui wu-hui assigned schmidt-sebastian and unassigned wu-hui Jul 23, 2020
@@ -532,6 +540,10 @@ export class WebStorageSharedClientState implements SharedClientState {

this.onlineStateKey = createWebStorageOnlineStateKey(this.persistenceKey);

this.bundleChangedRemoteDocumentsKey = createRemoteDocumentsLoadFromBundleKey(
Copy link
Contributor

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.

Copy link
Contributor Author

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 {
Copy link
Contributor

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.

@wu-hui wu-hui merged commit 9bfb995 into wuandy/Bundles Jul 23, 2020
@firebase firebase locked and limited conversation to collaborators Aug 23, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants