use of org.janusgraph.diskstorage.util.KeyColumn in project janusgraph by JanusGraph.
the class ExpectedValueCheckingTest method testMutateManyWithLockUsesConsistentTx.
@Test
public void testMutateManyWithLockUsesConsistentTx() throws BackendException {
final ImmutableList<Entry> adds = ImmutableList.of(StaticArrayEntry.of(DATA_COL, DATA_VAL));
final ImmutableList<StaticBuffer> deletions = ImmutableList.of();
Map<String, Map<StaticBuffer, KCVMutation>> mutations = ImmutableMap.of(STORE_NAME, ImmutableMap.of(DATA_KEY, new KCVMutation(adds, deletions)));
final KeyColumn kc = new KeyColumn(LOCK_KEY, LOCK_COL);
// Acquire a lock
backingLocker.writeLock(kc, consistentTx);
// 2. Run mutateMany
// 2.1. Check locks & expected values before mutating data
backingLocker.checkLocks(consistentTx);
StaticBuffer nextBuf = BufferUtil.nextBiggerBuffer(kc.getColumn());
KeySliceQuery expectedValueQuery = new KeySliceQuery(kc.getKey(), kc.getColumn(), nextBuf);
// expected value read must use strong consistency
expect(backingStore.getSlice(expectedValueQuery, consistentTx)).andReturn(StaticArrayEntryList.of(StaticArrayEntry.of(LOCK_COL, LOCK_VAL)));
// 2.2. Run mutateMany on backing manager to modify data
// writes by txs with locks must use strong consistency
backingManager.mutateMany(mutations, consistentTx);
ctrl.replay();
// Lock acquisition
expectStore.acquireLock(LOCK_KEY, LOCK_COL, LOCK_VAL, expectTx);
// Mutate
expectManager.mutateMany(mutations, expectTx);
}
use of org.janusgraph.diskstorage.util.KeyColumn in project janusgraph by JanusGraph.
the class LockKeyColumnValueStoreTest method testLocksOnMultipleStores.
@Test
public void testLocksOnMultipleStores() throws Exception {
// the number of stores must be a multiple of 3
final int numStores = 6;
final StaticBuffer key = BufferUtil.getLongBuffer(1);
final StaticBuffer col = BufferUtil.getLongBuffer(2);
final StaticBuffer val2 = BufferUtil.getLongBuffer(8);
// Create mocks
LockerProvider mockLockerProvider = createStrictMock(LockerProvider.class);
Locker mockLocker = createStrictMock(Locker.class);
// Create EVCSManager with mockLockerProvider
ExpectedValueCheckingStoreManager expManager = new ExpectedValueCheckingStoreManager(manager[0], "multi_store_lock_mgr", mockLockerProvider, Duration.ofMillis(100L));
// Begin EVCTransaction
BaseTransactionConfig txCfg = StandardBaseTransactionConfig.of(times);
ExpectedValueCheckingTransaction tx = expManager.beginTransaction(txCfg);
// openDatabase calls getLocker, and we do it numStores times
expect(mockLockerProvider.getLocker(anyObject(String.class))).andReturn(mockLocker).times(numStores);
// acquireLock calls writeLock, and we do it 2/3 * numStores times
mockLocker.writeLock(eq(new KeyColumn(key, col)), eq(tx.getConsistentTx()));
expectLastCall().times(numStores / 3 * 2);
// mutateMany calls checkLocks, and we do it 2/3 * numStores times
mockLocker.checkLocks(tx.getConsistentTx());
expectLastCall().times(numStores / 3 * 2);
replay(mockLockerProvider);
replay(mockLocker);
/*
* Acquire a lock on several distinct stores (numStores total distinct
* stores) and build mutations.
*/
ImmutableMap.Builder<String, Map<StaticBuffer, KCVMutation>> builder = ImmutableMap.builder();
for (int i = 0; i < numStores; i++) {
String storeName = "multi_store_lock_" + i;
KeyColumnValueStore s = expManager.openDatabase(storeName);
if (i % 3 < 2)
s.acquireLock(key, col, null, tx);
if (i % 3 > 0) {
builder.put(storeName, ImmutableMap.of(key, new KCVMutation(ImmutableList.of(StaticArrayEntry.of(col, val2)), ImmutableList.of())));
}
}
// Mutate
expManager.mutateMany(builder.build(), tx);
// Shutdown
expManager.close();
// Check the mocks
verify(mockLockerProvider);
verify(mockLocker);
}
use of org.janusgraph.diskstorage.util.KeyColumn in project janusgraph by JanusGraph.
the class ExpectedValueCheckingStore method acquireLock.
/**
* {@inheritDoc}
* <p/>
* This implementation supports locking when {@code lockStore} is non-null.
* <p/>
* Consider the following scenario. This method is called twice with
* identical key, column, and txh arguments, but with different
* expectedValue arguments in each call. In testing, it seems JanusGraph's
* graphdb requires that implementations discard the second expectedValue
* and, when checking expectedValues vs actual values just prior to mutate,
* only the initial expectedValue argument should be considered.
*/
@Override
public void acquireLock(StaticBuffer key, StaticBuffer column, StaticBuffer expectedValue, StoreTransaction txh) throws BackendException {
if (locker != null) {
ExpectedValueCheckingTransaction tx = (ExpectedValueCheckingTransaction) txh;
if (tx.isMutationStarted())
throw new PermanentLockingException("Attempted to obtain a lock after mutations had been persisted");
KeyColumn lockID = new KeyColumn(key, column);
log.debug("Attempting to acquireLock on {} ev={}", lockID, expectedValue);
locker.writeLock(lockID, tx.getConsistentTx());
tx.storeExpectedValue(this, lockID, expectedValue);
} else {
store.acquireLock(key, column, expectedValue, unwrapTx(txh));
}
}
use of org.janusgraph.diskstorage.util.KeyColumn in project janusgraph by JanusGraph.
the class AbstractLocker method deleteLocks.
@Override
public void deleteLocks(StoreTransaction tx) throws TemporaryLockingException, PermanentLockingException {
if (null != tx.getConfiguration().getGroupName()) {
MetricManager.INSTANCE.getCounter(tx.getConfiguration().getGroupName(), M_LOCKS, M_DELETE, M_CALLS).inc();
}
Map<KeyColumn, S> m = lockState.getLocksForTx(tx);
final Iterator<Map.Entry<KeyColumn, S>> iterator = m.entrySet().iterator();
while (iterator.hasNext()) {
final Map.Entry<KeyColumn, S> entry = iterator.next();
final KeyColumn kc = entry.getKey();
final S ls = entry.getValue();
try {
deleteSingleLock(kc, ls, tx);
} catch (AssertionError ae) {
// Concession to ease testing with mocks & behavior verification
throw ae;
} catch (Throwable t) {
log.error("Exception while deleting lock on " + kc, t);
if (null != tx.getConfiguration().getGroupName()) {
MetricManager.INSTANCE.getCounter(tx.getConfiguration().getGroupName(), M_LOCKS, M_DELETE, M_CALLS).inc();
}
}
// Regardless of whether we successfully deleted the lock from storage, take it out of the local mediator
llm.unlock(kc, tx);
iterator.remove();
}
}
use of org.janusgraph.diskstorage.util.KeyColumn in project janusgraph by JanusGraph.
the class ExpectedValueCheckingTest method testMutateWithLockUsesConsistentTx.
@Test
public void testMutateWithLockUsesConsistentTx() throws BackendException {
final ImmutableList<Entry> adds = ImmutableList.of(StaticArrayEntry.of(DATA_COL, DATA_VAL));
final ImmutableList<StaticBuffer> deletions = ImmutableList.of();
final KeyColumn kc = new KeyColumn(LOCK_KEY, LOCK_COL);
// 1. Acquire a lock
backingLocker.writeLock(kc, consistentTx);
// 2. Run a mutation
// N.B. mutation coordinates do not overlap with the lock, but consistentTx should be used anyway
// 2.1. Check locks & expected values before mutating data
backingLocker.checkLocks(consistentTx);
StaticBuffer nextBuf = BufferUtil.nextBiggerBuffer(kc.getColumn());
KeySliceQuery expectedValueQuery = new KeySliceQuery(kc.getKey(), kc.getColumn(), nextBuf);
// expected value read must use strong consistency
expect(backingStore.getSlice(expectedValueQuery, consistentTx)).andReturn(StaticArrayEntryList.of(StaticArrayEntry.of(LOCK_COL, LOCK_VAL)));
// 2.2. Mutate data
// writes by txs with locks must use strong consistency
backingStore.mutate(DATA_KEY, adds, deletions, consistentTx);
ctrl.replay();
// 1. Lock acquisition
expectStore.acquireLock(LOCK_KEY, LOCK_COL, LOCK_VAL, expectTx);
// 2. Mutate
expectStore.mutate(DATA_KEY, adds, deletions, expectTx);
}
Aggregations