Skip to content

b/72533250: Fix issue with limbo resolutions triggering incorrect manufactured deletes. #1556

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 2 commits into from
Jul 19, 2018

Conversation

mikelehen
Copy link
Contributor

@mikelehen mikelehen commented Jul 18, 2018

Note: I wrote C++ code so please review carefully.

[Port of firebase/firebase-js-sdk#1014]

This fixes an issue occurring when a limbo target receives a documentUpdate,
then a global snapshot, and then a CURRENT. Because there was a global
snapshot before the CURRENT, WatchChangeAggregator has no pending document
updates and calls SyncEngine.remoteKeysForTarget to see if we previously got any
document from the backend for the target. See:
https://github.com/firebase/firebase-js-sdk/blob/6905339235ad801291edc696dd75a08e80647f5b/packages/firestore/src/remote/watch_change.ts#L422

Prior to this change, remoteKeysForTarget returned empty because
it relies on our Views to track the contents of the target, and we don't
have Views for limbo targets. Thus WatchChangeAggregator incorrectly
manufactures a NoDocument document update which deletes data from our
cache.

The fix is to have SyncEngine track the fact that we did indeed get
a document for the limbo resolution and return it from
remoteKeysForTarget.

…ufactured deletes.

[Port of firebase/firebase-js-sdk#1014]

This fixes an issue occurring when a limbo target receives a documentUpdate,
then a global snapshot, and then a CURRENT. Because there was a global
snapshot before the CURRENT, WatchChangeAggregator has no pending document
updates and calls SyncEngine.remoteKeysForTarget to see if we previously got any
document from the backend for the target. See:
https://github.com/firebase/firebase-js-sdk/blob/6905339235ad801291edc696dd75a08e80647f5b/packages/firestore/src/remote/watch_change.ts#L422

Prior to this change, remoteKeysForTarget returned empty because
it relies on our Views to track the contents of the target, and we don't
have Views for limbo targets. Thus WatchChangeAggregator incorrectly
manufactures a NoDocument document update which deletes data from our
cache.

The fix is to have SyncEngine track the fact that we did indeed get
a document for the limbo resolution and return it from
remoteKeysForTarget.
Copy link
Contributor

@wilhuff wilhuff left a comment

Choose a reason for hiding this comment

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

Basically LGTM with style nits.

/** Tracks a limbo resolution. */
class LimboResolution {
public:
LimboResolution() : key{DocumentKey()} {
Copy link
Contributor

Choose a reason for hiding this comment

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

DocumentKey as a non-POD type will default initialize itself so you don't need to explicitly default initialize key. bool is a POD type so it has no default initializer, so you do need to initialize it.

Rather than repeat the initialization of documentReceived, add a default assignment below (bool document_received = false;).

With that in place, this can just be

LimboResolution() {
}

* ultimately used by FSTWatchChangeAggregator to decide whether it needs to manufacture a delete
* event for the target once the target is CURRENT.
*/
bool documentReceived;
Copy link
Contributor

Choose a reason for hiding this comment

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

fields are snake_case.

// Since this is a limbo resolution lookup, it's for a single document and it could be
// added, modified, or removed, but not a combination.
HARD_ASSERT(change.addedDocuments.size() + change.modifiedDocuments.size() +
change.removedDocuments.size() <=
Copy link
Contributor

Choose a reason for hiding this comment

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

Did clang-format really do this? Yikes.

@@ -484,7 +536,7 @@ - (void)trackLimboChange:(FSTLimboDocumentChange *)limboChange {
targetID:limboTargetID
listenSequenceNumber:kIrrelevantSequenceNumber
purpose:FSTQueryPurposeLimboResolution];
_limboKeysByTarget[limboTargetID] = key;
_limboResolutionsByTarget[limboTargetID] = LimboResolution{key};
Copy link
Contributor

Choose a reason for hiding this comment

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

This default constructs the LimboResolution and then assigns it. Better to make this:

_limboResolutionsByTarget.emplace(limboTargetID, LimboResolution{key});

@wilhuff wilhuff assigned mikelehen and unassigned wilhuff Jul 19, 2018
@wilhuff
Copy link
Contributor

wilhuff commented Jul 19, 2018

In the interest of time I've just fixed the style issues.

Copy link
Contributor

@wilhuff wilhuff left a comment

Choose a reason for hiding this comment

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

LGTM

@mikelehen
Copy link
Contributor Author

Hah, thanks! :)

@mikelehen mikelehen merged commit c204a1c into master Jul 19, 2018
@mikelehen mikelehen deleted the mikelehen/limbo-deletes branch July 19, 2018 03:33
wilhuff pushed a commit that referenced this pull request Jul 19, 2018
…ufactured deletes. (#1556)

[Port of firebase/firebase-js-sdk#1014]

This fixes an issue occurring when a limbo target receives a documentUpdate,
then a global snapshot, and then a CURRENT. Because there was a global
snapshot before the CURRENT, WatchChangeAggregator has no pending document
updates and calls SyncEngine.remoteKeysForTarget to see if we previously got any
document from the backend for the target. See:
https://github.com/firebase/firebase-js-sdk/blob/6905339235ad801291edc696dd75a08e80647f5b/packages/firestore/src/remote/watch_change.ts#L422

Prior to this change, remoteKeysForTarget returned empty because
it relies on our Views to track the contents of the target, and we don't
have Views for limbo targets. Thus WatchChangeAggregator incorrectly
manufactures a NoDocument document update which deletes data from our
cache.

The fix is to have SyncEngine track the fact that we did indeed get
a document for the limbo resolution and return it from
remoteKeysForTarget.
@firebase firebase locked and limited conversation to collaborators Oct 30, 2019
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.

3 participants