use of org.apache.jackrabbit.oak.spi.state.NodeState in project jackrabbit-oak by apache.
the class DocumentNodeState method getChildNodeDoc.
//------------------------------< internal >--------------------------------
@CheckForNull
private AbstractDocumentNodeState getChildNodeDoc(String childNodeName) {
AbstractDocumentNodeState secondaryState = getSecondaryNodeState();
if (secondaryState != null) {
NodeState result = secondaryState.getChildNode(childNodeName);
//else return null
if (result.exists()) {
return (AbstractDocumentNodeState) result;
}
return null;
}
Matcher child = bundlingContext.matcher.next(childNodeName);
if (child.isMatch()) {
if (bundlingContext.hasChildNode(child.getMatchedPath())) {
return createBundledState(childNodeName, child);
} else {
return null;
}
}
return store.getNode(concat(getPath(), childNodeName), lastRevision);
}
use of org.apache.jackrabbit.oak.spi.state.NodeState in project jackrabbit-oak by apache.
the class DocumentNodeStoreBranch method merge0.
@Nonnull
private NodeState merge0(@Nonnull CommitHook hook, @Nonnull CommitInfo info, boolean exclusive) throws CommitFailedException {
CommitFailedException ex = null;
Set<Revision> conflictRevisions = new HashSet<Revision>();
long time = System.currentTimeMillis();
int numRetries = 0;
boolean suspended = false;
for (long backoff = MIN_BACKOFF; backoff <= maximumBackoff; backoff *= 2) {
if (ex != null) {
try {
numRetries++;
final long start = perfLogger.start();
// or as a fallback sleep for a while
if (!conflictRevisions.isEmpty()) {
// suspend until conflicting revision is visible
LOG.debug("Suspending until {} is visible. Current head {}.", conflictRevisions, store.getHeadRevision());
suspended = true;
store.suspendUntilAll(conflictRevisions);
conflictRevisions.clear();
LOG.debug("Resumed. Current head {}.", store.getHeadRevision());
} else {
Thread.sleep(backoff + RANDOM.nextInt((int) Math.min(backoff, Integer.MAX_VALUE)));
}
perfLogger.end(start, 1, "Merge - Retry attempt [{}]", numRetries);
} catch (InterruptedException e) {
throw new CommitFailedException(MERGE, 3, "Merge interrupted", e);
}
}
try {
NodeState result = branchState.merge(checkNotNull(hook), checkNotNull(info), exclusive);
store.getStatsCollector().doneMerge(numRetries, System.currentTimeMillis() - time, suspended, exclusive);
return result;
} catch (FailedWithConflictException e) {
ex = e;
conflictRevisions.addAll(e.getConflictRevisions());
} catch (CommitFailedException e) {
ex = e;
}
LOG.trace("Merge Error", ex);
// by a rebase and running the hook again
if (!ex.isOfType(MERGE)) {
throw ex;
}
}
// if we get here retrying failed
time = System.currentTimeMillis() - time;
store.getStatsCollector().failedMerge(numRetries, time, suspended, exclusive);
String msg = ex.getMessage() + " (retries " + numRetries + ", " + time + " ms)";
throw new CommitFailedException(ex.getSource(), ex.getType(), ex.getCode(), msg, ex.getCause());
}
use of org.apache.jackrabbit.oak.spi.state.NodeState in project jackrabbit-oak by apache.
the class MergingNodeStateDiff method resolveConflict.
//------------------------------------------------------------< private >---
private void resolveConflict(ConflictType conflictType, NodeState conflictInfo) {
PropertyConflictHandler propertyConflictHandler = propertyConflictHandlers.get(conflictType);
if (propertyConflictHandler != null) {
for (PropertyState ours : conflictInfo.getProperties()) {
PropertyState theirs = parent.getProperty(ours.getName());
Resolution resolution = propertyConflictHandler.resolve(ours, theirs);
applyResolution(resolution, conflictType, ours);
}
} else {
NodeConflictHandler nodeConflictHandler = nodeConflictHandlers.get(conflictType);
if (nodeConflictHandler != null) {
for (ChildNodeEntry oursCNE : conflictInfo.getChildNodeEntries()) {
String name = oursCNE.getName();
NodeState ours = oursCNE.getNodeState();
NodeState theirs = parent.getChildNode(name);
Resolution resolution = nodeConflictHandler.resolve(name, ours, theirs);
applyResolution(resolution, conflictType, name, ours);
if (LOG.isDebugEnabled()) {
String diff = JsopDiff.diffToJsop(ours, theirs);
LOG.debug("{} resolved conflict of type {} with resolution {} on node {}, conflict trace {}", nodeConflictHandler, conflictType, resolution, name, diff);
}
}
} else {
LOG.warn("Ignoring unknown conflict '" + conflictType + '\'');
}
}
NodeBuilder conflictMarker = getConflictMarker(conflictType);
if (conflictMarker != null) {
assert conflictMarker.getChildNodeCount(1) == 0;
}
}
use of org.apache.jackrabbit.oak.spi.state.NodeState in project jackrabbit-oak by apache.
the class ClusterRevisionComparisonTest method revisionComparisonTwoClusterNodes.
@Test
public void revisionComparisonTwoClusterNodes() throws Exception {
DocumentNodeStore c1 = createNS(1);
DocumentNodeStore c2 = createNS(2);
// 1. Create /a and make it visible to both cluster nodes
createNode(c1, "/a");
runBgOps(c1, c2);
// 2. Time T1. Create /a/c2 but do not push the changes yet rT1-C2
createNode(c2, "/a/c2");
// 3. Time T2. Create /a/c1
createNode(c1, "/a/c1");
// 4. Push changes on c2
runBgOps(c2);
// 5. Time T3. Read the changes /a/c2 by c2 created at T1.
// Now from C1 view rT1-C2 > rT2-C1 even though T1 < T2
runBgOps(c1);
DocumentNodeState c1ns1 = c1.getRoot();
NodeState a = c1ns1.getChildNode("a");
assertTrue("/a/c1 missing", a.hasChildNode("c1"));
assertTrue("/a/c2 missing", a.hasChildNode("c2"));
// 6. Purge revision comparator. Also purge entries from nodeCache
// such that later reads at rT1-C2 triggers read from underlying DocumentStore
c1.invalidateNodeCache("/a/c1", ((DocumentNodeState) a).getLastRevision());
c1.invalidateNodeCache("/a/c2", ((DocumentNodeState) a).getLastRevision());
runBgOps(c1);
assertTrue("/a/c1 disappeared", a.hasChildNode("c1"));
assertTrue("/a/c2 disappeared", a.hasChildNode("c2"));
// read again starting at root node with a invalidated cache
// and purged revision comparator
c1ns1 = c1.getRoot();
c1.invalidateNodeCache("/", c1ns1.getRootRevision());
c1ns1 = c1.getRoot();
c1.invalidateNodeCache("/a", c1ns1.getLastRevision());
assertTrue("/a missing", c1ns1.hasChildNode("a"));
a = c1ns1.getChildNode("a");
c1.invalidateNodeCache("/a/c1", ((DocumentNodeState) a).getLastRevision());
c1.invalidateNodeCache("/a/c2", ((DocumentNodeState) a).getLastRevision());
assertTrue("/a/c1 disappeared", a.hasChildNode("c1"));
assertTrue("/a/c2 disappeared", a.hasChildNode("c2"));
}
use of org.apache.jackrabbit.oak.spi.state.NodeState in project jackrabbit-oak by apache.
the class ClusterRevisionComparisonTest method revisionComparisonMultipleClusterNode.
@Test
public void revisionComparisonMultipleClusterNode() throws Exception {
DocumentNodeStore c1 = createNS(1);
DocumentNodeStore c2 = createNS(2);
DocumentNodeStore c3 = createNS(3);
//1. Create /a and make it visible to all cluster nodes
createNode(c1, "/a");
runBgOps(c1, c2, c3);
//2. Time T1. Create /a/c2 but do not push the changes yet rT1-C2
createNode(c2, "/a/c2");
//3. Time T2. Create /a/c3 and push the changes rT2-C3
createNode(c3, "/a/c3");
runBgOps(c3);
//4. Time T3. Read the changes /a/c3 by c3 created at T2
// would be considered seen at T3 i.e. rT2-C3 -> rT3-C1
runBgOps(c1);
//5. Push changes
runBgOps(c2);
//6. Time T4. Read the changes /a/c2 by c2 created at T1.
// Would be considered seen at T4 i.e. rT1-C2 -> rT4-C1
// Now from C1 view rT1-C2 > rT2-C3 even though T1 < T2
//so effectively changes done in future in C3 in absolute time terms
//is considered to be seen in past by C1
runBgOps(c1);
DocumentNodeState c1ns1 = c1.getRoot();
Iterables.size(c1ns1.getChildNode("a").getChildNodeEntries());
createNode(c1, "/a/c1");
//7. Purge revision comparator. Also purge entries from nodeCache
//such that later reads at rT1-C2 triggers read from underlying DocumentStore
c1.invalidateNodeCache("/a/c2", ((DocumentNodeState) c1ns1.getChildNode("a")).getLastRevision());
c1.invalidateNodeCache("/a/c3", ((DocumentNodeState) c1ns1.getChildNode("a")).getLastRevision());
runBgOps(c1);
NodeState a = c1ns1.getChildNode("a");
assertTrue("/a/c2 disappeared", a.hasChildNode("c2"));
assertTrue("/a/c3 disappeared", a.hasChildNode("c3"));
DocumentNodeState c1ns2 = c1.getRoot();
//Trigger a diff. With OAK-2144 an exception would be thrown as diff traverses
//the /a children
c1ns1.compareAgainstBaseState(c1ns2, new TrackingDiff());
}
Aggregations