Search in sources :

Example 86 with StaticBuffer

use of org.janusgraph.diskstorage.StaticBuffer in project janusgraph by JanusGraph.

the class ConsistentKeyLocker method writeSingleLock.

/**
 * Try to write a lock record remotely up to the configured number of
 *  times. If the store produces
 * {@link TemporaryLockingException}, then we'll call mutate again to add a
 * new column with an updated timestamp and to delete the column that tried
 * to write when the store threw an exception. We continue like that up to
 * the retry limit. If the store throws anything else, such as an unchecked
 * exception or a {@link org.janusgraph.diskstorage.PermanentBackendException}, then we'll try to
 * delete whatever we added and return without further retries.
 *
 * @param lockID lock to acquire
 * @param txh    transaction
 * @return the timestamp, in nanoseconds since UNIX Epoch, on the lock
 *         column that we successfully wrote to the store
 * @throws TemporaryLockingException if the lock retry count is exceeded without successfully
 *                                   writing the lock in less than the wait limit
 * @throws Throwable                 if the storage layer throws anything else
 */
@Override
protected ConsistentKeyLockStatus writeSingleLock(KeyColumn lockID, StoreTransaction txh) throws Throwable {
    final StaticBuffer lockKey = serializer.toLockKey(lockID.getKey(), lockID.getColumn());
    StaticBuffer oldLockCol = null;
    for (int i = 0; i < lockRetryCount; i++) {
        WriteResult wr = tryWriteLockOnce(lockKey, oldLockCol, txh);
        if (wr.isSuccessful() && wr.getDuration().compareTo(lockWait) <= 0) {
            final Instant writeInstant = wr.getWriteTimestamp();
            final Instant expireInstant = writeInstant.plus(lockExpire);
            return new ConsistentKeyLockStatus(writeInstant, expireInstant);
        }
        oldLockCol = wr.getLockCol();
        handleMutationFailure(lockID, lockKey, wr, txh);
    }
    tryDeleteLockOnce(lockKey, oldLockCol, txh);
    // TODO log exception or successful too-slow write here
    throw new TemporaryBackendException("Lock write retry count exceeded");
}
Also used : TemporaryBackendException(org.janusgraph.diskstorage.TemporaryBackendException) Instant(java.time.Instant) StaticBuffer(org.janusgraph.diskstorage.StaticBuffer)

Example 87 with StaticBuffer

use of org.janusgraph.diskstorage.StaticBuffer in project janusgraph by JanusGraph.

the class ConsistentKeyLocker method deleteSingleLock.

@Override
protected void deleteSingleLock(KeyColumn kc, ConsistentKeyLockStatus ls, StoreTransaction tx) {
    List<StaticBuffer> deletions = Collections.singletonList(serializer.toLockCol(ls.getWriteTimestamp(), rid, times));
    for (int i = 0; i < lockRetryCount; i++) {
        StoreTransaction newTx = null;
        try {
            newTx = overrideTimestamp(tx, times.getTime());
            store.mutate(serializer.toLockKey(kc.getKey(), kc.getColumn()), Collections.emptyList(), deletions, newTx);
            newTx.commit();
            newTx = null;
            return;
        } catch (TemporaryBackendException e) {
            log.warn("Temporary storage exception while deleting lock", e);
        // don't return -- iterate and retry
        } catch (BackendException e) {
            log.error("Storage exception while deleting lock", e);
            // give up on this lock
            return;
        } finally {
            rollbackIfNotNull(newTx);
        }
    }
}
Also used : TemporaryBackendException(org.janusgraph.diskstorage.TemporaryBackendException) StoreTransaction(org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction) StaticBuffer(org.janusgraph.diskstorage.StaticBuffer) TemporaryBackendException(org.janusgraph.diskstorage.TemporaryBackendException) BackendException(org.janusgraph.diskstorage.BackendException) PermanentBackendException(org.janusgraph.diskstorage.PermanentBackendException)

Example 88 with StaticBuffer

use of org.janusgraph.diskstorage.StaticBuffer in project janusgraph by JanusGraph.

the class BufferUtil method readEntry.

public static Entry readEntry(ReadBuffer in, Serializer serializer) {
    long valuePosition = VariableLong.readPositive(in);
    Preconditions.checkArgument(valuePosition > 0 && valuePosition <= Integer.MAX_VALUE);
    StaticBuffer buffer = readBuffer(in);
    StaticArrayEntry entry = new StaticArrayEntry(buffer, (int) valuePosition);
    int metaSize = in.getByte();
    for (int i = 0; i < metaSize; i++) {
        EntryMetaData meta = EntryMetaData.values()[in.getByte()];
        entry.setMetaData(meta, serializer.readObjectNotNull(in, meta.getDataType()));
    }
    return entry;
}
Also used : StaticBuffer(org.janusgraph.diskstorage.StaticBuffer) EntryMetaData(org.janusgraph.diskstorage.EntryMetaData)

Example 89 with StaticBuffer

use of org.janusgraph.diskstorage.StaticBuffer in project janusgraph by JanusGraph.

the class ConsistentKeyLockerTest method expectDeleteLock.

private void expectDeleteLock(KeyColumn lockID, StaticBuffer lockKey, ConsistentKeyLockStatus lockStatus, BackendException... backendFailures) throws BackendException {
    List<StaticBuffer> deletions = ImmutableList.of(codec.toLockCol(lockStatus.getWriteTimestamp(), defaultLockRid, times));
    expect(times.getTime()).andReturn(currentTimeNS);
    store.mutate(eq(lockKey), eq(ImmutableList.of()), eq(deletions), eq(defaultTx));
    int backendExceptionsThrown = 0;
    for (BackendException e : backendFailures) {
        expectLastCall().andThrow(e);
        if (e instanceof PermanentBackendException) {
            break;
        }
        backendExceptionsThrown++;
        int maxTemporaryStorageExceptions = 3;
        if (backendExceptionsThrown < maxTemporaryStorageExceptions) {
            expect(times.getTime()).andReturn(currentTimeNS);
            store.mutate(eq(lockKey), eq(ImmutableList.of()), eq(deletions), eq(defaultTx));
        }
    }
    expect(mediator.unlock(lockID, defaultTx)).andReturn(true);
}
Also used : PermanentBackendException(org.janusgraph.diskstorage.PermanentBackendException) StaticBuffer(org.janusgraph.diskstorage.StaticBuffer) TemporaryBackendException(org.janusgraph.diskstorage.TemporaryBackendException) BackendException(org.janusgraph.diskstorage.BackendException) PermanentBackendException(org.janusgraph.diskstorage.PermanentBackendException)

Example 90 with StaticBuffer

use of org.janusgraph.diskstorage.StaticBuffer in project janusgraph by JanusGraph.

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 org.janusgraph.diskstorage.BackendException shouldn't happen
 */
@Test
public void testWriteLockThrowsExceptionAfterMaxStoreTimeouts() throws BackendException {
    expect(lockState.has(defaultTx, defaultLockID)).andReturn(false);
    recordSuccessfulLocalLock();
    StaticBuffer firstCol = recordSuccessfulLockWrite(5, ChronoUnit.SECONDS, null).col;
    StaticBuffer secondCol = recordSuccessfulLockWrite(5, ChronoUnit.SECONDS, firstCol).col;
    StaticBuffer thirdCol = recordSuccessfulLockWrite(5, ChronoUnit.SECONDS, secondCol).col;
    recordSuccessfulLockDelete(thirdCol);
    recordSuccessfulLocalUnlock();
    ctrl.replay();
    BackendException expected = null;
    try {
        // SUT
        locker.writeLock(defaultLockID, defaultTx);
    } catch (TemporaryBackendException e) {
        expected = e;
    }
    assertNotNull(expected);
}
Also used : TemporaryBackendException(org.janusgraph.diskstorage.TemporaryBackendException) StaticBuffer(org.janusgraph.diskstorage.StaticBuffer) TemporaryBackendException(org.janusgraph.diskstorage.TemporaryBackendException) BackendException(org.janusgraph.diskstorage.BackendException) PermanentBackendException(org.janusgraph.diskstorage.PermanentBackendException) Test(org.junit.jupiter.api.Test)

Aggregations

StaticBuffer (org.janusgraph.diskstorage.StaticBuffer)101 Entry (org.janusgraph.diskstorage.Entry)36 Test (org.junit.jupiter.api.Test)36 ArrayList (java.util.ArrayList)27 HashMap (java.util.HashMap)20 Map (java.util.Map)19 StoreTransaction (org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction)17 KeySliceQuery (org.janusgraph.diskstorage.keycolumnvalue.KeySliceQuery)16 StaticArrayEntry (org.janusgraph.diskstorage.util.StaticArrayEntry)16 BackendException (org.janusgraph.diskstorage.BackendException)15 List (java.util.List)14 EntryList (org.janusgraph.diskstorage.EntryList)14 TemporaryBackendException (org.janusgraph.diskstorage.TemporaryBackendException)14 KCVMutation (org.janusgraph.diskstorage.keycolumnvalue.KCVMutation)13 PermanentBackendException (org.janusgraph.diskstorage.PermanentBackendException)12 Instant (java.time.Instant)11 DataOutput (org.janusgraph.graphdb.database.serialize.DataOutput)10 ReadBuffer (org.janusgraph.diskstorage.ReadBuffer)8 ConsistentKeyLockStatus (org.janusgraph.diskstorage.locking.consistentkey.ConsistentKeyLockStatus)7 BackendOperation (org.janusgraph.diskstorage.util.BackendOperation)7