public class DocumentDiscoveryLiteService extends Object implements ClusterStateChangeListener, org.apache.jackrabbit.oak.spi.commit.Observer
The clusterView is provided via a repository descriptor (see OAK_DISCOVERYLITE_CLUSTERVIEW)
The cluster-view lists all instances (ever) known in the cluster in one of the following states:
Additionally, the cluster-view is assigned a monotonically increasing sequence number to. This sequence number is persisted, thus all instances in the cluster will show the same sequence number for a particular cluster-view in time.
Note that the 'deactivating' state might be hiding some complexity that is deliberately not shown: for the documentNS the state 'deactivating' consists of two substates: 'recovering' as in _lastRevs are updated, and 'backlog processing' for a pending backgroundRead to get the latest head state of a crashed/shutdown instance. So when an instance is in 'deactivating' state, it is not indicated via the cluster-view whether it is recovering or has backlog to process. However, the fact that an instance has to yet do a backgroundRead to get changes is a per-instance story: other instances might already have done the backgroundRead and thus no longer have a backlog for the instance(s) that left. Even though 'deactivating' therefore is dependent on the instance you get the information from, the cluster-view must have a sequence number that uniquely identifies it in the cluster. These two constraints conflict. As a simple solution to handle this case nevertheless, the 'final' flag has been introduced: the cluster-view has this flag 'final' set to true when the view is final and nothing will be changed in this sequence number anymore. If the 'final' flag is false however it indicates that the cluster-view with this particular sequence number might still experience a change (more concretely: the deactivating instances might change). Note that there alternatives to this 'final' flag have been discussed, such as using vector-counters, but there was no obvious gain achieve using an alternative approach.
In other words: whenever the 'final' flag is false, the view must be interpreted as 'in flux' wrt the deactivating/inactive instances and any action that depends on stable deactivating/inactive instances must not yet be done until the 'final' flag becomes true.
Underneath, the DocumentDiscoveryLiteService uses the clusterNodes collection to derive the clusterView, which it stores in the settings collection. Whenever it updates the clusterView it increments the sequence number by 1.
While this new 'clusterView' document in the settings collection sounds like redundant data (since it is just derived from the clusterNodes), it actually is not. By persisting the clusterView it becomes the new source of truth wrt what the clusterView looks like. And no two instances in the same cluster can make different conclusions based eg on different clocks they have or based on reading the clusterNodes in a slightly different moment etc. Also, the clusterView allows to store a the sequence number (which allows the instances to make reference to the same clusterView, and be able to simply detect whether anything has changed)
Prerequisites that the clusterView mechanism is stable:
OAK_DISCOVERYLITE_CLUSTERVIEW| Modifier and Type | Field and Description |
|---|---|
static String |
OAK_DISCOVERYLITE_CLUSTERVIEW
Name of the repository descriptor via which the clusterView is published
- which is the raison d'etre of the DocumentDiscoveryLiteService
|
| Constructor and Description |
|---|
DocumentDiscoveryLiteService() |
| Modifier and Type | Method and Description |
|---|---|
void |
activate(org.osgi.service.component.ComponentContext context)
On activate the DocumentDiscoveryLiteService tries to start the
background job
|
void |
contentChanged(@NotNull org.apache.jackrabbit.oak.spi.state.NodeState root,
@NotNull org.apache.jackrabbit.oak.spi.commit.CommitInfo info)
Additionally the DocumentDiscoveryLiteService must be notified when the
background-read has finished - as it could be waiting for a crashed
node's recovery to finish - which it can only do by checking the
lastKnownRevision of the crashed instance - and that check is best done
after the background read is just finished (it could optinoally do that
just purely time based as well, but going via a listener is more timely,
that's why this approach has been chosen).
|
protected void |
deactivate()
On deactivate the background job is stopped - if it was running at all
|
void |
handleClusterStateChange()
Informs the listener that DocumentNodeStore has discovered a change in
the clusterNodes collection.
|
public static final String OAK_DISCOVERYLITE_CLUSTERVIEW
public void activate(org.osgi.service.component.ComponentContext context)
protected void deactivate()
public void handleClusterStateChange()
ClusterStateChangeListenerhandleClusterStateChange in interface ClusterStateChangeListenerpublic void contentChanged(@NotNull
@NotNull org.apache.jackrabbit.oak.spi.state.NodeState root,
@NotNull
@NotNull org.apache.jackrabbit.oak.spi.commit.CommitInfo info)
Additionally the DocumentDiscoveryLiteService must be notified when the background-read has finished - as it could be waiting for a crashed node's recovery to finish - which it can only do by checking the lastKnownRevision of the crashed instance - and that check is best done after the background read is just finished (it could optinoally do that just purely time based as well, but going via a listener is more timely, that's why this approach has been chosen).
contentChanged in interface org.apache.jackrabbit.oak.spi.commit.ObserverCopyright © 2012–2018 The Apache Software Foundation. All rights reserved.