use of com.thinkaurelius.titan.diskstorage.StaticBuffer 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);
}
use of com.thinkaurelius.titan.diskstorage.StaticBuffer in project titan by thinkaurelius.
the class ConsistentKeyLockerTest method testWriteLockRetriesAfterOneStoreTimeout.
/**
* Test locker when first attempt to write to the store takes too long (but
* succeeds). Expected behavior is to call mutate on the store, adding a
* column with a new timestamp and deleting the column with the old
* (too-slow-to-write) timestamp.
*
* @throws StorageException shouldn't happen
*/
@Test
public void testWriteLockRetriesAfterOneStoreTimeout() throws StorageException {
expect(lockState.has(defaultTx, defaultLockID)).andReturn(false);
recordSuccessfulLocalLock();
// too slow
StaticBuffer firstCol = recordSuccessfulLockWrite(5, TimeUnit.SECONDS, null).col;
// plenty fast
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);
}
use of com.thinkaurelius.titan.diskstorage.StaticBuffer in project titan by thinkaurelius.
the class ConsistentKeyLockerTest method testCheckLocksRetriesAfterSingleTemporaryStorageException.
/**
* The checker should retry getSlice() in the face of a
* TemporaryStorageException so long as the number of exceptional
* getSlice()s is fewer than the lock retry count. The retry count applies
* on a per-lock basis.
*
* @throws StorageException shouldn't happen
* @throws InterruptedException shouldn't happen
*/
@Test
public void testCheckLocksRetriesAfterSingleTemporaryStorageException() throws StorageException, InterruptedException {
// Setup one lock column
StaticBuffer lockCol = codec.toLockCol(currentTimeNS, defaultLockRid);
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);
// First getSlice will fail
TemporaryStorageException tse = new TemporaryStorageException("Storage cluster will be right back");
recordExceptionalLockGetSlice(tse);
// Second getSlice will succeed
recordLockGetSliceAndReturnSingleEntry(new StaticBufferEntry(lockCol, defaultLockVal));
ctrl.replay();
locker.checkLocks(defaultTx);
// TODO run again with two locks instead of one and show that the retry count applies on a per-lock basis
}
use of com.thinkaurelius.titan.diskstorage.StaticBuffer in project titan by thinkaurelius.
the class ConsistentKeyLockerTest method testWriteLockDiesOnPermanentStorageException.
/**
* Test that the first {@link PermanentStorageException} thrown by the
* locker's store causes it to attempt to delete outstanding lock writes and
* then emit the exception without retrying.
*
* @throws StorageException shouldn't happen
*/
@Test
public void testWriteLockDiesOnPermanentStorageException() throws StorageException {
PermanentStorageException errOnFire = new PermanentStorageException("Storage cluster is on fire");
expect(lockState.has(defaultTx, defaultLockID)).andReturn(false);
recordSuccessfulLocalLock();
StaticBuffer lockCol = recordExceptionLockWrite(1, TimeUnit.NANOSECONDS, null, errOnFire);
recordSuccessfulLockDelete(1, TimeUnit.NANOSECONDS, lockCol);
recordSuccessfulLocalUnlock();
ctrl.replay();
StorageException expected = null;
try {
// SUT
locker.writeLock(defaultLockID, defaultTx);
} catch (PermanentLockingException e) {
expected = e;
}
assertNotNull(expected);
assertEquals(errOnFire, expected.getCause());
}
use of com.thinkaurelius.titan.diskstorage.StaticBuffer in project titan by thinkaurelius.
the class ConsistentKeyLockerTest method testDeleteLocksSkipsToNextLockAfterMaxTemporaryStorageExceptions.
/**
* If lock deletion exceeds the temporary exception retry count when trying
* to delete a lock, it should move onto the next lock rather than returning
* and potentially leaving the remaining locks undeleted.
*
* @throws StorageException shouldn't happen
*/
@Test
public void testDeleteLocksSkipsToNextLockAfterMaxTemporaryStorageExceptions() throws StorageException {
ConsistentKeyLockStatus defaultLS = makeStatusNow();
currentTimeNS++;
expect(lockState.getLocksForTx(defaultTx)).andReturn(Maps.newLinkedHashMap(ImmutableMap.of(defaultLockID, defaultLS)));
List<StaticBuffer> dels = ImmutableList.of(codec.toLockCol(defaultLS.getWriteTimestamp(TimeUnit.NANOSECONDS), defaultLockRid));
expect(times.getApproxNSSinceEpoch()).andReturn(currentTimeNS);
store.mutate(eq(defaultLockKey), eq(ImmutableList.<Entry>of()), eq(dels), eq(defaultTx));
expectLastCall().andThrow(new TemporaryStorageException("Storage cluster is busy"));
expect(times.getApproxNSSinceEpoch()).andReturn(currentTimeNS);
store.mutate(eq(defaultLockKey), eq(ImmutableList.<Entry>of()), eq(dels), eq(defaultTx));
expectLastCall().andThrow(new TemporaryStorageException("Storage cluster is busier"));
expect(times.getApproxNSSinceEpoch()).andReturn(currentTimeNS);
store.mutate(eq(defaultLockKey), eq(ImmutableList.<Entry>of()), eq(dels), eq(defaultTx));
expectLastCall().andThrow(new TemporaryStorageException("Storage cluster has reached peak business"));
expect(mediator.unlock(defaultLockID, defaultTx)).andReturn(true);
// lockState.release(defaultTx, defaultLockID);
ctrl.replay();
locker.deleteLocks(defaultTx);
}
Aggregations