use of org.apache.jackrabbit.oak.api.CommitFailedException in project jackrabbit-oak by apache.
the class DocumentNodeStoreBranch method acquireMergeLock.
/**
* Acquires the merge lock either exclusive or shared.
*
* @param exclusive whether to acquire the merge lock exclusive.
* @return the acquired merge lock or {@code null} if the operation timed
* out.
* @throws CommitFailedException if the current thread is interrupted while
* acquiring the lock
*/
@CheckForNull
private Lock acquireMergeLock(boolean exclusive) throws CommitFailedException {
final long start = perfLogger.start();
Lock lock;
if (exclusive) {
lock = mergeLock.writeLock();
} else {
lock = mergeLock.readLock();
}
boolean acquired;
try {
acquired = lock.tryLock(maxLockTryTimeMS, MILLISECONDS);
} catch (InterruptedException e) {
throw new CommitFailedException(OAK, 1, "Unable to acquire merge lock", e);
}
String mode = exclusive ? "exclusive" : "shared";
if (acquired) {
perfLogger.end(start, 1, "Merge - Acquired lock ({})", mode);
} else {
LOG.info("Time out while acquiring merge lock ({})", mode);
lock = null;
}
return lock;
}
use of org.apache.jackrabbit.oak.api.CommitFailedException 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.api.CommitFailedException in project jackrabbit-oak by apache.
the class ClusterConflictTest method suspendUntilVisible.
private void suspendUntilVisible(boolean withBranch) throws Exception {
NodeBuilder b1 = ns1.getRoot().builder();
b1.child("counter").setProperty("value", 0);
merge(ns1, b1);
ns1.runBackgroundOperations();
ns2.runBackgroundOperations();
b1 = ns1.getRoot().builder();
b1.child("foo");
ns1.merge(b1, new TestHook(), EMPTY);
final List<Exception> exceptions = Lists.newArrayList();
final NodeBuilder b2 = ns2.getRoot().builder();
b2.child("bar");
if (withBranch) {
purge(b2);
}
b2.child("baz");
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
LOG.info("initiating merge");
ns2.merge(b2, new TestHook(), EMPTY);
LOG.info("merge succeeded");
} catch (CommitFailedException e) {
exceptions.add(e);
}
}
});
t.start();
// wait until t is suspended
for (int i = 0; i < 100; i++) {
if (ns2.commitQueue.numSuspendedThreads() > 0) {
break;
}
Thread.sleep(10);
}
assertEquals(1, ns2.commitQueue.numSuspendedThreads());
LOG.info("commit suspended");
ns1.runBackgroundOperations();
LOG.info("ran background ops on ns1");
ns2.runBackgroundOperations();
LOG.info("ran background ops on ns2");
assertEquals(0, ns2.commitQueue.numSuspendedThreads());
t.join(3000);
assertFalse("Commit did not succeed within 3 seconds", t.isAlive());
for (Exception e : exceptions) {
throw e;
}
}
use of org.apache.jackrabbit.oak.api.CommitFailedException in project jackrabbit-oak by apache.
the class ConflictExceptionTest method type.
@Test
public void type() {
ConflictException e = new ConflictException("conflict");
CommitFailedException cfe = e.asCommitFailedException();
assertEquals(CommitFailedException.MERGE, cfe.getType());
}
use of org.apache.jackrabbit.oak.api.CommitFailedException in project jackrabbit-oak by apache.
the class ConcurrentReadAndAddTest method addNode.
private void addNode(int i) {
try {
NodeBuilder builder = ns.getRoot().builder();
builder.child("test").child("node-" + i);
merge(builder);
} catch (CommitFailedException e) {
exceptions.add(e);
}
}
Aggregations