use of com.thinkaurelius.titan.diskstorage.TemporaryStorageException 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.TemporaryStorageException 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);
}
use of com.thinkaurelius.titan.diskstorage.TemporaryStorageException in project titan by thinkaurelius.
the class AstyanaxStoreManager method ensureColumnFamilyExists.
private void ensureColumnFamilyExists(String name, String comparator) throws StorageException {
Cluster cl = clusterContext.getClient();
try {
KeyspaceDefinition ksDef = cl.describeKeyspace(keySpaceName);
boolean found = false;
if (null != ksDef) {
for (ColumnFamilyDefinition cfDef : ksDef.getColumnFamilyList()) {
found |= cfDef.getName().equals(name);
}
}
if (!found) {
ColumnFamilyDefinition cfDef = cl.makeColumnFamilyDefinition().setName(name).setKeyspace(keySpaceName).setComparatorType(comparator);
ImmutableMap.Builder<String, String> compressionOptions = new ImmutableMap.Builder<String, String>();
if (compressionEnabled) {
compressionOptions.put("sstable_compression", compressionClass).put("chunk_length_kb", Integer.toString(compressionChunkSizeKB));
}
cl.addColumnFamily(cfDef.setCompressionOptions(compressionOptions.build()));
}
} catch (ConnectionException e) {
throw new TemporaryStorageException(e);
}
}
use of com.thinkaurelius.titan.diskstorage.TemporaryStorageException in project titan by thinkaurelius.
the class AstyanaxStoreManager method mutateMany.
@Override
public void mutateMany(Map<String, Map<StaticBuffer, KCVMutation>> batch, StoreTransaction txh) throws StorageException {
MutationBatch m = keyspaceContext.getClient().prepareMutationBatch().setConsistencyLevel(getTx(txh).getWriteConsistencyLevel().getAstyanaxConsistency()).withRetryPolicy(retryPolicy.duplicate());
final Timestamp timestamp = getTimestamp(txh);
for (Map.Entry<String, Map<StaticBuffer, KCVMutation>> batchentry : batch.entrySet()) {
String storeName = batchentry.getKey();
Preconditions.checkArgument(openStores.containsKey(storeName), "Store cannot be found: " + storeName);
ColumnFamily<ByteBuffer, ByteBuffer> columnFamily = openStores.get(storeName).getColumnFamily();
Map<StaticBuffer, KCVMutation> mutations = batchentry.getValue();
for (Map.Entry<StaticBuffer, KCVMutation> ent : mutations.entrySet()) {
// The CLMs for additions and deletions are separated because
// Astyanax's operation timestamp cannot be set on a per-delete
// or per-addition basis.
KCVMutation titanMutation = ent.getValue();
if (titanMutation.hasDeletions()) {
ColumnListMutation<ByteBuffer> dels = m.withRow(columnFamily, ent.getKey().asByteBuffer());
dels.setTimestamp(timestamp.deletionTime);
for (StaticBuffer b : titanMutation.getDeletions()) dels.deleteColumn(b.asByteBuffer());
}
if (titanMutation.hasAdditions()) {
ColumnListMutation<ByteBuffer> upds = m.withRow(columnFamily, ent.getKey().asByteBuffer());
upds.setTimestamp(timestamp.additionTime);
for (Entry e : titanMutation.getAdditions()) upds.putColumn(e.getColumn().asByteBuffer(), e.getValue().asByteBuffer());
}
}
}
try {
m.execute();
} catch (ConnectionException e) {
throw new TemporaryStorageException(e);
}
}
use of com.thinkaurelius.titan.diskstorage.TemporaryStorageException in project titan by thinkaurelius.
the class CassandraThriftStoreManager method ensureKeyspaceExists.
private KsDef ensureKeyspaceExists(String keyspaceName) throws NotFoundException, InvalidRequestException, TException, SchemaDisagreementException, StorageException {
CTConnection connection = null;
try {
connection = pool.borrowObject(SYSTEM_KS);
Cassandra.Client client = connection.getClient();
try {
// Side effect: throws Exception if keyspaceName doesn't exist
// Don't remove
client.set_keyspace(keyspaceName);
client.set_keyspace(SYSTEM_KS);
log.debug("Found existing keyspace {}", keyspaceName);
} catch (InvalidRequestException e) {
// Keyspace didn't exist; create it
log.debug("Creating keyspace {}...", keyspaceName);
KsDef ksdef = new KsDef().setName(keyspaceName).setCf_defs(// cannot be null but can be empty
new LinkedList<CfDef>()).setStrategy_class("org.apache.cassandra.locator.SimpleStrategy").setStrategy_options(ImmutableMap.of("replication_factor", String.valueOf(replicationFactor)));
client.set_keyspace(SYSTEM_KS);
try {
client.system_add_keyspace(ksdef);
log.debug("Created keyspace {}", keyspaceName);
} catch (InvalidRequestException ire) {
log.error("system_add_keyspace failed for keyspace=" + keyspaceName, ire);
throw ire;
}
}
return client.describe_keyspace(keyspaceName);
} catch (Exception e) {
throw new TemporaryStorageException(e);
} finally {
pool.returnObjectUnsafe(SYSTEM_KS, connection);
}
}
Aggregations