use of com.thinkaurelius.titan.diskstorage.TemporaryStorageException in project titan by thinkaurelius.
the class ConsistentKeyLockerTest method testWriteLockThrowsExceptionAfterMaxStoreTimeouts.
/**
* Test locker when all three attempts to write a lock succeed but take
* longer than the wait limit. We expect the locker to delete all three
* columns that it wrote and locally unlock the KeyColumn, then emit an
* exception.
*
* @throws StorageException shouldn't happen
*/
@Test
public void testWriteLockThrowsExceptionAfterMaxStoreTimeouts() throws StorageException {
expect(lockState.has(defaultTx, defaultLockID)).andReturn(false);
recordSuccessfulLocalLock();
StaticBuffer firstCol = recordSuccessfulLockWrite(5, TimeUnit.SECONDS, null).col;
StaticBuffer secondCol = recordSuccessfulLockWrite(5, TimeUnit.SECONDS, firstCol).col;
StaticBuffer thirdCol = recordSuccessfulLockWrite(5, TimeUnit.SECONDS, secondCol).col;
recordSuccessfulLockDelete(1, TimeUnit.NANOSECONDS, thirdCol);
recordSuccessfulLocalUnlock();
ctrl.replay();
StorageException expected = null;
try {
// SUT
locker.writeLock(defaultLockID, defaultTx);
} catch (TemporaryStorageException e) {
expected = e;
}
assertNotNull(expected);
}
use of com.thinkaurelius.titan.diskstorage.TemporaryStorageException in project titan by thinkaurelius.
the class ConsistentKeyLockerTest method testCheckLocksThrowsExceptionAfterMaxTemporaryStorageExceptions.
/**
* The checker will throw a TemporaryStorageException if getSlice() throws
* fails with a TemporaryStorageException as many times as there are
* configured lock retries.
*
* @throws InterruptedException shouldn't happen
* @throws StorageException shouldn't happen
*/
@Test
public void testCheckLocksThrowsExceptionAfterMaxTemporaryStorageExceptions() throws InterruptedException, StorageException {
// Setup a LockStatus for defaultLockID
ConsistentKeyLockStatus lockStatus = makeStatusNow();
currentTimeNS += TimeUnit.NANOSECONDS.convert(1, TimeUnit.NANOSECONDS);
expect(lockState.getLocksForTx(defaultTx)).andReturn(ImmutableMap.of(defaultLockID, lockStatus));
expect(times.sleepUntil(lockStatus.getWriteTimestamp(TimeUnit.NANOSECONDS) + defaultWaitNS)).andReturn(currentTimeNS);
// Three successive getSlice calls, each throwing a distinct TSE
recordExceptionalLockGetSlice(new TemporaryStorageException("Storage cluster is having me-time"));
recordExceptionalLockGetSlice(new TemporaryStorageException("Storage cluster is in a dissociative fugue state"));
recordExceptionalLockGetSlice(new TemporaryStorageException("Storage cluster has gone to Prague to find itself"));
ctrl.replay();
TemporaryStorageException tse = null;
try {
locker.checkLocks(defaultTx);
} catch (TemporaryStorageException e) {
tse = e;
}
assertNotNull(tse);
}
use of com.thinkaurelius.titan.diskstorage.TemporaryStorageException in project titan by thinkaurelius.
the class MockIDAuthority method getIDBlock.
@Override
public synchronized long[] getIDBlock(int partition) throws StorageException {
// Delay artificially
if (delayAcquisitionMS > 0) {
try {
Thread.sleep(delayAcquisitionMS);
} catch (InterruptedException e) {
throw new TemporaryStorageException(e);
}
}
Integer p = Integer.valueOf(partition);
long size = blockSizer.getBlockSize(partition);
AtomicLong id = ids.get(p);
if (id == null) {
ids.putIfAbsent(p, new AtomicLong(1));
id = ids.get(p);
}
long lowerBound = id.getAndAdd(size);
if (lowerBound >= blockSizeLimit) {
throw new IDPoolExhaustedException("Reached partition limit: " + blockSizeLimit);
}
return new long[] { lowerBound, Math.min(lowerBound + size, blockSizeLimit) };
}
use of com.thinkaurelius.titan.diskstorage.TemporaryStorageException in project titan by thinkaurelius.
the class BackendOperation method execute.
public static final <V> V execute(Callable<V> exe, int maxRetryAttempts, long retryWaittime) throws TitanException {
Preconditions.checkArgument(maxRetryAttempts > 0, "Retry attempts must be positive");
Preconditions.checkArgument(retryWaittime >= 0, "Retry wait time must be non-negative");
int retryAttempts = 0;
StorageException lastException = null;
do {
try {
return exe.call();
} catch (StorageException e) {
if (e instanceof TemporaryStorageException)
lastException = e;
else
// Its permanent
throw new TitanException("Permanent exception during backend operation", e);
} catch (Throwable e) {
throw new TitanException("Unexpected exception during backend operation", e);
}
// Wait and retry
retryAttempts++;
Preconditions.checkNotNull(lastException);
if (retryAttempts < maxRetryAttempts) {
long waitTime = Math.round(retryWaittime + ((Math.random() * WAITTIME_PERTURBATION_PERCENTAGE - WAITTIME_PERTURBATION_PERCENTAGE_HALF) * retryWaittime));
Preconditions.checkArgument(waitTime >= 0, "Invalid wait time: %s", waitTime);
log.info("Temporary storage exception during backend operation [{}]. Attempting incremental retry", exe.toString(), lastException);
try {
Thread.sleep(waitTime);
} catch (InterruptedException r) {
throw new TitanException("Interrupted while waiting to retry failed backend operation", r);
}
}
} while (retryAttempts < maxRetryAttempts);
throw new TitanException("Could not successfully complete backend operation due to repeated temporary exceptions after " + maxRetryAttempts + " attempts", lastException);
}
use of com.thinkaurelius.titan.diskstorage.TemporaryStorageException in project titan by thinkaurelius.
the class ConsistentKeyLockerTest method testWriteLockRetriesOnTemporaryStorageException.
/**
* Test the locker retries a lock write after the initial store mutation
* fails with a {@link TemporaryStorageException}. The retry should both
* attempt to write the and delete the failed mutation column.
*
* @throws StorageException shouldn't happen
*/
@Test
public void testWriteLockRetriesOnTemporaryStorageException() throws StorageException {
TemporaryStorageException tse = new TemporaryStorageException("Storage cluster is waking up");
expect(lockState.has(defaultTx, defaultLockID)).andReturn(false);
recordSuccessfulLocalLock();
StaticBuffer firstCol = recordExceptionLockWrite(1, TimeUnit.NANOSECONDS, null, tse);
LockInfo secondLI = recordSuccessfulLockWrite(1, TimeUnit.NANOSECONDS, firstCol);
recordSuccessfulLocalLock(secondLI.tsNS);
lockState.take(eq(defaultTx), eq(defaultLockID), eq(secondLI.stat));
ctrl.replay();
// SUT
locker.writeLock(defaultLockID, defaultTx);
}
Aggregations