You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ch...@apache.org on 2014/04/02 08:14:03 UTC
svn commit: r1583892 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document:
ClusterNodeInfo.java ClusterNodeInfoDocument.java
Author: chetanm
Date: Wed Apr 2 06:14:02 2014
New Revision: 1583892
URL: http://svn.apache.org/r1583892
Log:
OAK-1295 - Recovery for missing _lastRev updates (WIP)
Refactor
-- to use enum for string constant
-- clock handling moved to single method
-- Strongly type getters for property
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfo.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfoDocument.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfo.java?rev=1583892&r1=1583891&r2=1583892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfo.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfo.java Wed Apr 2 06:14:02 2014
@@ -61,25 +61,48 @@ public class ClusterNodeInfo {
protected static final String LEASE_END_KEY = "leaseEnd";
/**
- * The state of the cluster.
- * On proper shutdown the state should be cleared.
- */
- protected static final String STATE = "state";
+ * The state of the cluster. On proper shutdown the state should be cleared.
+ *
+ * @see org.apache.jackrabbit.oak.plugins.document.ClusterNodeInfo.ClusterNodeState
+ */
+ public static final String STATE = "state";
+
+ public static enum ClusterNodeState {
+ NONE,
+ /**
+ * Indicates that cluster node is currently active
+ */
+ ACTIVE;
+
+ static ClusterNodeState fromString(String state){
+ if(state == null){
+ return NONE;
+ }
+ return valueOf(state);
+ }
+ }
/**
* Flag to indicate whether the _lastRev recovery is in progress.
+ *
+ * @see RecoverLockState
*/
- protected static final String REV_RECOVERY_LOCK = "revLock";
+ public static final String REV_RECOVERY_LOCK = "recoveryLock";
- /**
- * Active State.
- */
- private static final String ACTIVE_STATE = "active";
-
- /**
- * _lastRev recovery in progress
- */
- protected static final String REV_RECOVERY_ON = "true";
+ public static enum RecoverLockState {
+ NONE,
+ /**
+ * _lastRev recovery in progress
+ */
+ ACQUIRED;
+
+ static RecoverLockState fromString(String state){
+ if(state == null){
+ return NONE;
+ }
+ return valueOf(state);
+ }
+ }
/**
* Additional info, such as the process id, for support.
@@ -87,7 +110,8 @@ public class ClusterNodeInfo {
private static final String INFO_KEY = "info";
/**
- * The read/write mode key.
+ * The read/write mode key. Specifies the read/write preference to be used with
+ * DocumentStore
*/
private static final String READ_WRITE_MODE_KEY = "readWriteMode";
@@ -109,7 +133,7 @@ public class ClusterNodeInfo {
/**
* <b>Only Used For Testing</b>
*/
- private static Clock clock;
+ private static Clock clock = Clock.SIMPLE;
/**
* The number of milliseconds for a lease (1 minute by default, and
@@ -160,26 +184,17 @@ public class ClusterNodeInfo {
/**
* The state of the cluter node.
*/
- private String state;
+ private ClusterNodeState state;
/**
* The revLock value of the cluster;
*/
- private String revRecoveryLock;
-
- ClusterNodeInfo(int id, DocumentStore store, String machineId, String instanceId) {
- this.id = id;
- this.startTime = (clock == null ? System.currentTimeMillis() : clock.getTime());
- this.leaseEndTime = startTime;
- this.store = store;
- this.machineId = machineId;
- this.instanceId = instanceId;
- }
+ private RecoverLockState revRecoveryLock;
- ClusterNodeInfo(int id, DocumentStore store, String machineId, String instanceId, String state,
- String revRecoveryLock) {
+ ClusterNodeInfo(int id, DocumentStore store, String machineId, String instanceId, ClusterNodeState state,
+ RecoverLockState revRecoveryLock) {
this.id = id;
- this.startTime = (clock == null ? System.currentTimeMillis() : clock.getTime());
+ this.startTime = getCurrentTime();
this.leaseEndTime = startTime;
this.store = store;
this.machineId = machineId;
@@ -193,13 +208,6 @@ public class ClusterNodeInfo {
}
/**
- * <b>Only Used For Testing</b>
- */
- static void setClock(Clock c) {
- clock = c;
- }
-
- /**
* Create a cluster node info instance for the store, with the
*
* @param store the document store (for the lease)
@@ -231,12 +239,10 @@ public class ClusterNodeInfo {
update.set(ID, String.valueOf(clusterNode.id));
update.set(MACHINE_ID_KEY, clusterNode.machineId);
update.set(INSTANCE_ID_KEY, clusterNode.instanceId);
- update.set(LEASE_END_KEY,
- (clock == null ? System.currentTimeMillis() : clock.getTime())
- + clusterNode.leaseTime);
+ update.set(LEASE_END_KEY, getCurrentTime() + clusterNode.leaseTime);
update.set(INFO_KEY, clusterNode.toString());
- update.set(STATE, clusterNode.state);
- update.set(REV_RECOVERY_LOCK, clusterNode.revRecoveryLock);
+ update.set(STATE, clusterNode.state.name());
+ update.set(REV_RECOVERY_LOCK, clusterNode.revRecoveryLock.name());
boolean success =
store.create(Collection.CLUSTER_NODES, Collections.singletonList(update));
if (success) {
@@ -248,13 +254,14 @@ public class ClusterNodeInfo {
private static ClusterNodeInfo createInstance(DocumentStore store, String machineId,
String instanceId) {
- long now = (clock == null ? System.currentTimeMillis() : clock.getTime());
+ long now = getCurrentTime();
// keys between "0" and "a" includes all possible numbers
List<ClusterNodeInfoDocument> list = store.query(Collection.CLUSTER_NODES,
- "0", "a", Integer.MAX_VALUE);
+ ClusterNodeInfoDocument.MIN_ID_VALUE, ClusterNodeInfoDocument.MAX_ID_VALUE,
+ Integer.MAX_VALUE);
int clusterNodeId = 0;
int maxId = 0;
- String state = null;
+ ClusterNodeState state = ClusterNodeState.NONE;
for (Document doc : list) {
String key = doc.getId();
int id;
@@ -286,13 +293,13 @@ public class ClusterNodeInfo {
if (clusterNodeId == 0 || id < clusterNodeId) {
// if there are multiple, use the smallest value
clusterNodeId = id;
- state = (String) doc.get(STATE);
+ state = ClusterNodeState.fromString((String) doc.get(STATE));
}
}
if (clusterNodeId == 0) {
clusterNodeId = maxId + 1;
}
- return new ClusterNodeInfo(clusterNodeId, store, machineId, instanceId, state, null);
+ return new ClusterNodeInfo(clusterNodeId, store, machineId, instanceId, state, RecoverLockState.NONE);
}
/**
@@ -302,14 +309,14 @@ public class ClusterNodeInfo {
* @param nextCheckMillis the millisecond offset
*/
public void renewLease(long nextCheckMillis) {
- long now = (clock == null ? System.currentTimeMillis() : clock.getTime());
+ long now = getCurrentTime();
if (now + nextCheckMillis + nextCheckMillis < leaseEndTime) {
return;
}
UpdateOp update = new UpdateOp("" + id, true);
leaseEndTime = now + leaseTime;
update.set(LEASE_END_KEY, leaseEndTime);
- update.set(STATE, ACTIVE_STATE);
+ update.set(STATE, ClusterNodeState.ACTIVE.name());
ClusterNodeInfoDocument doc = store.createOrUpdate(Collection.CLUSTER_NODES, update);
String mode = (String) doc.get(READ_WRITE_MODE_KEY);
if (mode != null && !mode.equals(readWriteMode)) {
@@ -347,6 +354,19 @@ public class ClusterNodeInfo {
"revLock: " + revRecoveryLock;
}
+ /**
+ * Specify a custom clock to be used for determining current time.
+ * If passed clock is null then clock would be set to the default clock
+ *
+ * <b>Only Used For Testing</b>
+ */
+ static void setClock(Clock c) {
+ if(c == null){
+ c = Clock.SIMPLE;
+ }
+ clock = c;
+ }
+
private static long getProcessId() {
try {
String name = ManagementFactory.getRuntimeMXBean().getName();
@@ -388,4 +408,8 @@ public class ClusterNodeInfo {
return RANDOM_PREFIX + UUID.randomUUID().toString();
}
+ private static long getCurrentTime() {
+ return clock.getTime();
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfoDocument.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfoDocument.java?rev=1583892&r1=1583891&r2=1583892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfoDocument.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfoDocument.java Wed Apr 2 06:14:02 2014
@@ -16,11 +16,44 @@
*/
package org.apache.jackrabbit.oak.plugins.document;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.apache.jackrabbit.oak.plugins.document.ClusterNodeInfo.ClusterNodeState;
+import static org.apache.jackrabbit.oak.plugins.document.ClusterNodeInfo.RecoverLockState;
+
/**
* A document storing cluster node info. See also {@link ClusterNodeInfo}.
*/
public class ClusterNodeInfoDocument extends Document {
- // marker interface
+ /**
+ * All ClusterNodeInfoDocument ID value would be greater than this value
+ * It can be used as startKey in DocumentStore#query methods
+ */
+ public static final String MIN_ID_VALUE = "0";
+
+ /**
+ * All ClusterNodeInfoDocument ID value would be less than this value
+ * It can be used as endKey in DocumentStore#query methods
+ */
+ public static final String MAX_ID_VALUE = "a";
+
+ public long getLeaseEndTime(){
+ return checkNotNull((Long) get(ClusterNodeInfo.LEASE_END_KEY), "Lease End Time not set");
+ }
+
+ public boolean isActive(){
+ return getState() == ClusterNodeState.ACTIVE;
+ }
+
+ public boolean isBeingRecovered(){
+ return getRecoveryState() == RecoverLockState.ACQUIRED;
+ }
+
+ private ClusterNodeState getState(){
+ return ClusterNodeState.fromString((String) get(ClusterNodeInfo.STATE));
+ }
+ private RecoverLockState getRecoveryState(){
+ return RecoverLockState.fromString((String) get(ClusterNodeInfo.REV_RECOVERY_LOCK));
+ }
}