Skip to content

Conversation

@adamchel
Copy link
Contributor

I did this by basically adding the spec to the code as comments. there were several places where I had to add missing functionality, and there’s at least one place where I’m not sure if we need to add more to the spec to make it complete.

I didn’t add any tests since I figured existing tests cover this, and some of the previously unimplemented features of the sync algorithm are more for optimization than correctness.

@adamchel adamchel requested review from edaniels and jsflax October 19, 2018 23:21
@coveralls
Copy link

coveralls commented Oct 19, 2018

Coverage Status

Coverage decreased (-0.6%) to 59.235% when pulling c9052c4 on adamchel:STITCH-1960-rebased into a881f34 on mongodb:master.

Copy link
Contributor

@jsflax jsflax left a comment

Choose a reason for hiding this comment

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

Looks good! This really cleans up the R2L/L2R logic.

Few nits (mostly language related), and a possible minor related to clearing events once "processing" them.

logicalT,
eventEntry.getValue().getOperationType()));

// i. Find the corresponding local document.
Copy link
Contributor

Choose a reason for hiding this comment

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

[nit] i. Find the corresponding local document config. Orthologically and semantically, these are different concepts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good, but this means changing the spec as well since I copied directly from there.

}

// TODO(QUESTION FOR REVIEW): This code is not in the spec, but if I don't include it, then
// testInsertThenSyncUpdateThenUpdate will fail. Should I add it to the spec?
Copy link
Contributor

Choose a reason for hiding this comment

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

In my opinion, it would be helpful to add to the spec. This is more than just an implementation detail.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's this in spec:

drop the event if the version counter of the remote event less than or equal to the version counter of the local document

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But that's in a different place. The way the spec is written, this check is only made "if the document does not have local writes pending". Does this mean we should reorder the spec so that the check occurs before the "If the document does not have local writes pending" check?

Copy link
Contributor

Choose a reason for hiding this comment

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

I suppose it should be changed in the spec. We do this check if we have changes or not.

docConfig.getDocumentId(),
remoteChangeEvent.getOperationType().toString()));
break;
return;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice, I caught this in my current ticket as well.


// 1. If both the local document version and the remote change event version are empty, drop
// the event. The absence of a version is effectively a version, and the pending write will
// set a version on the next L2R pass if it’s not a delete.
Copy link
Contributor

Choose a reason for hiding this comment

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

[nit] Might be nice to add the relative bits of this to the hasVersion doc string.

continue;
}

// i. Retrieve the synthetic change event for this local document in the local config
Copy link
Contributor

Choose a reason for hiding this comment

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

[nit] We may want to be careful about using the word synthetic here. Local events exist in a transient state, but are arguably real. Synthetic as term makes more sense when we are generating remote events based on conflict, and do not have actual data about what the remote change event was. I feel it's important that we do not conflate terminology here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright, removing the word synthetic, and updating the spec as well.

this.emitError(docConfig, String.format(
// ii. Check if the internal remote change stream listener has an unprocessed event for
// this document.
final ChangeEvent<BsonDocument> unprocessedRemoteEvent =
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice seeing this to spec.

*
* @return the latest unprocessed change event for the given document ID, or null if none exists.
*/
public @Nullable ChangeEvent<BsonDocument> getUnprocessedEventForDocumentId(
Copy link
Contributor

Choose a reason for hiding this comment

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

[minor?] Once this event is read, shouldn't it be considered processed? That was the logic behind clearing the map in getEvents– once they've been read, they have been processed. It seems like we should be removing them here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed with Jason. This isn't a bug but it would cause us to keep doing work that's not needed.

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, good catch, took me longer than it should have to wrap my head around this. I thought that because this is L2R we're not actually processing the event, and that we should wait for R2L to actually process it, but you're right that in any case, the event here is being effectively dropped or used to raise a conflict, so I'll fix this and clarify the comments here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Clarified the comments, and added a suggestion to the spec as well.

Copy link
Contributor

@edaniels edaniels left a comment

Choose a reason for hiding this comment

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

Great work. LGTM after Jason's comments are resolved.

@adamchel
Copy link
Contributor Author

@jsflax PTAL.

also @edaniels I made relevant changes to the spec. if you make any changes to what I added, let me know so I can update the comments in the code

Copy link
Contributor

@jsflax jsflax left a comment

Choose a reason for hiding this comment

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

LGTM!

@adamchel adamchel merged commit 94ea1fe into mongodb:master Oct 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants