Skip to content
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

Tree-Shakeable Mutations #3329

Merged
merged 5 commits into from
Jul 6, 2020
Merged

Tree-Shakeable Mutations #3329

merged 5 commits into from
Jul 6, 2020

Conversation

schmidt-sebastian
Copy link
Contributor

@schmidt-sebastian schmidt-sebastian commented Jun 30, 2020

The goal of this PR is to remove the latency-compensation only features that Mutations currently offer. The idea is to include applyToLocalView and applyToRemoteDocument only in the full-featured SDK. While the approach in this SDK ties to different Mutation types together (a build cannot just depend on PatchMutation), this is already the case and I think it will be close to impossible to make the Mutations independent, as the are always tied together in the serializer.

Note that I tried a different approach: #3327 makes it so the Lite doesn't use Mutations at all, instead it uses writes. I am not a fan of how that turned out though.

Diff without whitespace: #3329 (much smaller)

@changeset-bot
Copy link

changeset-bot bot commented Jun 30, 2020

🦋 Changeset is good to go

Latest commit: 6c28d0b

We got this.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Jun 30, 2020

Binary Size Report

Affected SDKs

  • @firebase/firestore

    Type Base (fc17a3c) Head (91fe77e) Diff
    browser 248 kB 247 kB -1.16 kB (-0.5%)
    esm2017 194 kB 193 kB -230 B (-0.1%)
    main 493 kB 494 kB +591 B (+0.1%)
    module 245 kB 244 kB -1.20 kB (-0.5%)
    react-native 194 kB 194 kB -230 B (-0.1%)
  • @firebase/firestore/exp

    Type Base (fc17a3c) Head (91fe77e) Diff
    main 396 kB 398 kB +2.09 kB (+0.5%)
  • @firebase/firestore/lite

    Type Base (fc17a3c) Head (91fe77e) Diff
    main 134 kB 124 kB -10.2 kB (-7.6%)
  • @firebase/firestore/memory

    Type Base (fc17a3c) Head (91fe77e) Diff
    browser 185 kB 184 kB -1.16 kB (-0.6%)
    esm2017 145 kB 145 kB -225 B (-0.2%)
    main 363 kB 363 kB +596 B (+0.2%)
    module 184 kB 183 kB -1.20 kB (-0.7%)
    react-native 145 kB 145 kB -225 B (-0.2%)
  • firebase

    Type Base (fc17a3c) Head (91fe77e) Diff
    firebase-firestore.js 286 kB 285 kB -1.36 kB (-0.5%)
    firebase-firestore.memory.js 225 kB 224 kB -1.35 kB (-0.6%)
    firebase.js 819 kB 818 kB -1.35 kB (-0.2%)

Test Logs

@schmidt-sebastian schmidt-sebastian changed the title WIP Tree-Shakeable Mutations Tree-Shakeable Mutations Jul 1, 2020
@@ -123,7 +123,7 @@ export class ServerTimestampFieldValueImpl extends SerializableFieldValue {
}

_toFieldTransform(context: ParseContext): FieldTransform {
return new FieldTransform(context.path!, ServerTimestampTransform.instance);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed static instance member as these are not tree-shakeable. See #3264

Copy link
Contributor

Choose a reason for hiding this comment

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

I noticed we reference all the transforms inside of transform_operation.ts. Will the branches in that file get erased if we don't reference ServerTimestampTransform? It seems like we have a problem either way. Am I missing something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Given the way our serializer works (we look at the data in IndexedDB and then decide which transform to create), I don't think it is possible to structure our SDK in a way that ServerTimestampTransform is not included if another transform is used. Having ServerTimestampTransform.instance however means that ServerTimestampTransform may also be included in the final bundle if neither the serializer not the transforms are used at all.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's what I figured. imho - I think that if the final bundle takes the hit of including these types regardless of use we should consider maintaining the existing pattern. I was never a fan of the new style and and if we're not getting any benefit from it, why deviate?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The Lite SDK doesn't reference these methods and is able to remove them (see the binary size report: -7%). Does that answer your concern?

if (precondition.updateTime !== undefined) {
return (
maybeDoc instanceof Document &&
maybeDoc.version.isEqual(precondition.updateTime)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved this method out of Precondition because it pulls in Document.

* UnknownDocument if the mutation could not be applied to the locally
* cached base document.
*/
export function applyMutationToRemoteDocument(
Copy link
Contributor

Choose a reason for hiding this comment

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

Apologies in advance for this drive by comment :-).

Why is this pattern better than just having the lite SDK create the Write protos directly? This seems like way more code added and in the end the lite SDK still ends up with an intermediate object that contributes to the heft of the SDK.

When simplifying documents in the other SDKs we made them just wrap the protos. It seems like we could take a similar approach here: have the lite SDK to just build the protos and pass them down. The heavier-weight SDKs could reuse that code but then wrap the protos in classes that add local behavior.

This way we'd still end up with code sharing between the SDKs, the lite SDK ends up optimally lite (with every API call is just translation of arguments into protos and a REST invocation), but we don't end up having to deal with these instanceof ladders for behavior that doesn't fit in the lite SDK.

Note: this comment is really a question. I don't really understand why you disliked the outcome of #3327 and I don't understand what value mutations have in the lite SDK. If you're convinced this path is the way forward I'll be happy with that outcome but I just want to make sure because this pattern is kinda gross.

Copy link
Contributor Author

@schmidt-sebastian schmidt-sebastian Jul 1, 2020

Choose a reason for hiding this comment

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

The reason I don't like #3327:

  • It duplicates the Proto encoding for users that use the Write-proto based Transactions and non-transactional writes. This leads to a general size increase for the main SDK and firestore-exp.
  • It makes it impossible to share the WriteBatch between the firestore-exp and the Lite SDK.
  • It adds a lot of functions with names that I am not happy with.

@@ -123,7 +123,7 @@ export class ServerTimestampFieldValueImpl extends SerializableFieldValue {
}

_toFieldTransform(context: ParseContext): FieldTransform {
return new FieldTransform(context.path!, ServerTimestampTransform.instance);
Copy link
Contributor

Choose a reason for hiding this comment

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

I noticed we reference all the transforms inside of transform_operation.ts. Will the branches in that file get erased if we don't reference ServerTimestampTransform? It seems like we have a problem either way. Am I missing something?

Copy link
Contributor

@rafikhan rafikhan left a comment

Choose a reason for hiding this comment

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

I left one comment about the transforms. Otherwise LGTM.

@rafikhan rafikhan removed their assignment Jul 6, 2020
@schmidt-sebastian schmidt-sebastian merged commit c7aa053 into master Jul 6, 2020
@schmidt-sebastian schmidt-sebastian deleted the mrschmidt/mutations2 branch July 9, 2020 17:44
@firebase firebase locked and limited conversation to collaborators Aug 6, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants