-
Notifications
You must be signed in to change notification settings - Fork 620
Don't persist documents that we already have #720
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
@@ -395,8 +396,16 @@ public static RemoteEvent noChangeEvent(int targetId, int version, ByteString re | |||
|
|||
public static RemoteEvent addedRemoteEvent( | |||
MaybeDocument doc, List<Integer> updatedInTargets, List<Integer> removedFromTargets) { | |||
DocumentChange change = | |||
new DocumentChange(updatedInTargets, removedFromTargets, doc.getKey(), doc); | |||
return addedRemoteEvent(Collections.singletonList(doc), updatedInTargets, removedFromTargets); |
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.
Note: the changes here are also part of https://github.com/firebase/firebase-android-sdk/pull/697/files#diff-ac4f307b0804f62b9719e8c7556226c2L396
@@ -329,50 +329,35 @@ public SnapshotVersion getLastRemoteSnapshotVersion() { | |||
return persistence.runTransaction( | |||
"Apply remote event", | |||
() -> { | |||
SnapshotVersion remoteVersion = remoteEvent.getSnapshotVersion(); |
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.
Question: this variable is now much further from its first point of use, and I didn't notice any references to it in-between. Perhaps move it back to the end of this function?
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.
It's used in line 354. I moved it to the top of the function body - let me know if you think that's better. I can otherwise also inline the usage in line 354.
if (shouldPersistQueryData(oldQueryData, queryData, change)) { | ||
queryCache.updateQueryData(queryData); | ||
QueryData oldQueryData = targetIds.get(targetId); | ||
if (oldQueryData != 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.
Optional: I personally liked the continue
approach that was in place before (this function is long, and I feel the increased nestedness hurts readability).
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.
Sounds good. Reverted.
queryCache.removeMatchingKeys(change.getRemovedDocuments(), targetId); | ||
queryCache.addMatchingKeys(change.getAddedDocuments(), targetId); | ||
|
||
// Update the resume token if the change includes one. Don't clear any preexisting |
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.
Question: which code is responsible for Don't clear any preexisting value
-- is it shouldPersistQueryData
?
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.
Yes. I removed that part of the comment since it is a bit confusing.
for (Map.Entry<Integer, TargetChange> entry : targetChanges.entrySet()) { | ||
Integer boxedTargetId = entry.getKey(); | ||
int targetId = boxedTargetId; | ||
TargetChange change = entry.getValue(); | ||
|
||
// Do not ref/unref unassigned targetIds - it may lead to leaks. |
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.
Does this comment no longer apply?
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 rewrote it below since I didn't quite understand it at first.
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, cool. I also found the original comment confusing.
// version to the remote cache. | ||
|| doc.getVersion().compareTo(existingDoc.getVersion()) > 0 | ||
|| (doc.getVersion().compareTo(existingDoc.getVersion()) == 0 | ||
&& existingDoc.hasPendingWrites())) { |
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, why do we overwrite the existing doc when it has pending writes?
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 only important question, the rest are nitpicks.
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.
When the write stream sends us an acknowledgment, we persist a document with hasCommittedMutations
. We then pretend we know the state of the document, but that is not always true (another client may have changed a field we didn't write to, or we supplied an ArrayUnion/ArrayRemove transform that was applied to a set of elements that the client didn't yet know about). By allowing the server to send us the state of a committed document, we overwrite the hasCommittedMutations
version with the actual version from the backend.
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.
Thanks for the explanation!
Preconditions.checkArgument(!docs.isEmpty(), "Cannot pass empty docs array"); | ||
|
||
ResourcePath collectionPath = docs.get(0).getKey().getPath().popLast(); | ||
SnapshotVersion version = docs.get(0).getVersion(); |
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.
Optional: move this declaration to the point right before it's used?
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.
@@ -407,11 +416,16 @@ public static RemoteEvent addedRemoteEvent( | |||
|
|||
@Override | |||
public QueryData getQueryDataForTarget(int targetId) { | |||
return queryData(targetId, QueryPurpose.LISTEN, doc.getKey().toString()); | |||
return queryData(targetId, QueryPurpose.LISTEN, collectionPath.toString()); |
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.
Question: what's the reason for this change?
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.
The new test passes multiple docs to addedRemoteEvent
. The test helper now uses the collection path of the first doc to represent the query.
FWIW I also believe the original implementation should have returned a collection path here.
The public api surface has changed for the subproject firebase-firestore: Please update the api.txt files for the subprojects being affected by this change by running ./gradlew ${subproject}:generateApiTxtFile. Also perform a major/minor bump accordingly. |
for (Map.Entry<Integer, TargetChange> entry : targetChanges.entrySet()) { | ||
Integer boxedTargetId = entry.getKey(); | ||
int targetId = boxedTargetId; | ||
TargetChange change = entry.getValue(); | ||
|
||
// Do not ref/unref unassigned targetIds - it may lead to leaks. |
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, cool. I also found the original comment confusing.
Port of firebase/firebase-js-sdk#2099.
Also pulls in spec test changes from firebase/firebase-js-sdk#2098