Hi, On 16/02/16 09:56, "[email protected]<mailto:[email protected]> on behalf of Ian Boston" wrote: So, IIUC, (based on Revision.compareTo(Revision) used by StableRevisionComparitor.
yes. If one instance within a cluster has a clock that is lagging the others, and all instances are making changes at the same time, then the changes that the other instances make will be used, even the the lagging instance makes changes after (in real synchronised time) the others ? no, either cluster node has equal chances of getting its change in, but the other cluster node's change will be rejected. Let's assume we have two cluster nodes A and B and cluster node A's clock is lagging 5 seconds. Now both cluster nodes try to to set a property P on document D. One of the cluster nodes will be first to update document D. No matter, which cluster node is first, the second cluster node will see the previous change when it attempts the commit and will consider the change as not yet visible and in conflict with its own changes. The change of the second cluster node will therefore be rolled back. The behaviour of the cluster nodes will be different when external changes are pulled in from external cluster nodes. The background read operation of the DocumentNodeStore reads the most recent root document and compare the _lastRev entries of the other cluster nodes with its own clock (the _lastRev entries are the most recent commits visible to other cluster nodes). Here we have two cases: a) Cluster node A was successful to commit its change on P Cluster node A wrote a _lastRev on the root document for this change: r75-0-a. Cluster node B picks up that change and compares the revision with its own clock, which corresponds to r80-0-b (for readability, assuming for now the timestamp is a decimal and in seconds instead of milliseconds). Cluster node B will consider r75-0-a as visible from now on, because the timestamp of r80-0-b is newer than r75-0-a. From this point on Cluster node B can overwrite P again because it is able to see the most recent value set by A with r75-0-a. b) Cluster node B was successful to commit its change on P Cluster node B wrote a _lastRev on the root document for this change: r80-0-b. Cluster node A picks up that change and compares the revision with its own clock, which corresponds to r75-0-a. Cluster node A will still not consider r80-0-b as visible, because its own clock is considered behind. It will wait until its clock is passed r80-0-a. This makes a new change by A overwriting B's previous value of P, will have a newer timestamp than the previously made visible change of B. This means: 1) all changes considered visible can be compared with the StableRevisionComparator without the need to take clock differences into account. 2) a change will conflict if it is not the most recent revision (using StableRevisionComparator) or the other change is not yet visible but already committed. I can see that this won't matter for the majority of nodes, as collisions are rare, but won't the lagging instance be always overridden in the root document _revisions list ? Depending on usage, collisions are actually not that rare ;) The _revisions map on the root document contains just the commit entry. A cluster node cannot overwrite the entry of another cluster node, because they use unique revisions for commits. Each cluster node generates revisions with a unique clusterId suffix. Are there any plans to maintain a clock difference vector for the cluster ? Oak 1.0.x and 1.2.x still have something like this. See RevisionComparator. However, it only maintains the clock differences for the past 60 minutes. Oak 1.4 introduced a RevisionVector, which is inspired by version vectors [0]. Regards Marcel [0] https://issues.apache.org/jira/browse/OAK-3646?focusedCommentId=15028698&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-15028698
