Search in sources :

Example 1 with CASResult

use of org.apache.cassandra.thrift.CASResult in project atlasdb by palantir.

the class Heartbeat method beat.

private Void beat(CassandraClient client) throws TException {
    Column ourUpdate = SchemaMutationLock.lockColumnFromIdAndHeartbeat(lockId, heartbeatCount + 1);
    List<Column> expected = ImmutableList.of(SchemaMutationLock.lockColumnFromIdAndHeartbeat(lockId, heartbeatCount));
    if (Thread.currentThread().isInterrupted()) {
        log.debug("Cancelled {}", this);
        return null;
    }
    CASResult casResult = writeDdlLockWithCas(client, ourUpdate, expected);
    if (casResult.isSuccess()) {
        heartbeatCount++;
    } else {
        log.warn("Unable to update lock for {}", this);
        SchemaMutationLock.handleForcedLockClear(casResult, lockId, heartbeatCount);
    }
    log.debug("Completed {}", this);
    return null;
}
Also used : Column(org.apache.cassandra.thrift.Column) CASResult(org.apache.cassandra.thrift.CASResult)

Example 2 with CASResult

use of org.apache.cassandra.thrift.CASResult in project atlasdb by palantir.

the class CassandraKeyValueServiceImpl method putUnlessExists.

/**
 * Puts values into the key-value store. This call <i>does not</i> guarantee
 * atomicity across cells. On failure, it is possible that some of the requests will
 * have succeeded (without having been rolled back). Similarly, concurrent batched requests may
 * interleave.  However, concurrent writes to the same Cell will not both report success.
 * One of them will throw {@link KeyAlreadyExistsException}.
 * <p>
 * Does not require all Cassandra nodes to be up and available, works as long as quorum is achieved.
 *
 * @param tableRef the name of the table to put values into.
 * @param values map containing the key-value entries to put.
 *
 * @throws KeyAlreadyExistsException If you are putting a Cell with the same timestamp as one that already exists.
 */
@Override
public void putUnlessExists(final TableReference tableRef, final Map<Cell, byte[]> values) throws KeyAlreadyExistsException {
    try {
        clientPool.runWithRetry(client -> {
            for (Entry<Cell, byte[]> e : values.entrySet()) {
                CheckAndSetRequest request = CheckAndSetRequest.newCell(tableRef, e.getKey(), e.getValue());
                CASResult casResult = executeCheckAndSet(client, request);
                if (!casResult.isSuccess()) {
                    throw new KeyAlreadyExistsException(String.format("The row in table %s already exists.", tableRef.getQualifiedName()), ImmutableList.of(e.getKey()));
                }
            }
            clientPool.markWritesForTable(values, tableRef);
            return null;
        });
    } catch (Exception e) {
        throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
    }
}
Also used : CheckAndSetRequest(com.palantir.atlasdb.keyvalue.api.CheckAndSetRequest) Cell(com.palantir.atlasdb.keyvalue.api.Cell) KeyAlreadyExistsException(com.palantir.atlasdb.keyvalue.api.KeyAlreadyExistsException) InsufficientConsistencyException(com.palantir.atlasdb.keyvalue.api.InsufficientConsistencyException) CheckAndSetException(com.palantir.atlasdb.keyvalue.api.CheckAndSetException) KeyAlreadyExistsException(com.palantir.atlasdb.keyvalue.api.KeyAlreadyExistsException) FunctionCheckedException(com.palantir.common.base.FunctionCheckedException) TException(org.apache.thrift.TException) UnavailableException(org.apache.cassandra.thrift.UnavailableException) PalantirRuntimeException(com.palantir.common.exception.PalantirRuntimeException) CASResult(org.apache.cassandra.thrift.CASResult)

Example 3 with CASResult

use of org.apache.cassandra.thrift.CASResult in project atlasdb by palantir.

the class CassandraTimestampBoundStore method cas.

@GuardedBy("this")
private void cas(CassandraClient client, Long oldVal, long newVal) {
    final CASResult result;
    try {
        DebugLogger.logger.info("[CAS] Trying to set upper limit from {} to {}.", oldVal, newVal);
        result = client.cas(AtlasDbConstants.TIMESTAMP_TABLE, getRowName(), oldVal == null ? ImmutableList.of() : ImmutableList.of(makeColumn(oldVal)), ImmutableList.of(makeColumn(newVal)), ConsistencyLevel.SERIAL, ConsistencyLevel.EACH_QUORUM);
    } catch (Exception e) {
        log.error("[CAS] Error trying to set from {} to {}", SafeArg.of("oldValue", oldVal), SafeArg.of("newValue", newVal), e);
        DebugLogger.logger.error("[CAS] Error trying to set from {} to {}", SafeArg.of("oldValue", oldVal), SafeArg.of("newValue", newVal), e);
        throw Throwables.throwUncheckedException(e);
    }
    if (!result.isSuccess()) {
        final String msg = "Unable to CAS from {} to {}." + " Timestamp limit changed underneath us (limit in memory: {}, stored in DB: {})." + " This may indicate that another timestamp service is running against this cassandra keyspace." + " This is likely caused by multiple copies of a service running without a configured set of" + " leaders or a CLI being run with an embedded timestamp service against an already running" + " service.";
        MultipleRunningTimestampServiceError err = new MultipleRunningTimestampServiceError(String.format(replaceBracesWithStringFormatSpecifier(msg), oldVal, newVal, currentLimit, getCurrentTimestampValues(result)));
        log.error(msg, SafeArg.of("oldValue", oldVal), SafeArg.of("newValue", newVal), SafeArg.of("inMemoryLimit", currentLimit), SafeArg.of("dbLimit", getCurrentTimestampValues(result)), err);
        DebugLogger.logger.error(msg, SafeArg.of("oldValue", oldVal), SafeArg.of("newValue", newVal), SafeArg.of("inMemoryLimit", currentLimit), SafeArg.of("dbLimit", getCurrentTimestampValues(result)), err);
        DebugLogger.logger.error("Thread dump: {}", SafeArg.of("threadDump", ThreadDumps.programmaticThreadDump()));
        throw err;
    } else {
        DebugLogger.logger.debug("[CAS] Setting cached limit to {}.", newVal);
        currentLimit = newVal;
    }
}
Also used : MultipleRunningTimestampServiceError(com.palantir.timestamp.MultipleRunningTimestampServiceError) NotFoundException(org.apache.cassandra.thrift.NotFoundException) FunctionCheckedException(com.palantir.common.base.FunctionCheckedException) CASResult(org.apache.cassandra.thrift.CASResult) GuardedBy(javax.annotation.concurrent.GuardedBy)

Example 4 with CASResult

use of org.apache.cassandra.thrift.CASResult in project atlasdb by palantir.

the class SchemaMutationLock method trySchemaMutationUnlockOnce.

private boolean trySchemaMutationUnlockOnce(long perOperationNodeId) {
    try {
        return clientPool.runWithRetry(client -> {
            Column clearedLock = lockColumnWithValue(GLOBAL_DDL_LOCK_CLEARED_VALUE);
            Column existingColumn = queryExistingLockColumn(client).orElse(clearedLock);
            long existingLockId = getLockIdFromColumn(existingColumn);
            if (existingLockId == GLOBAL_DDL_LOCK_CLEARED_ID) {
                return true;
            }
            Preconditions.checkState(existingLockId == perOperationNodeId, "Trying to unlock lock [%s] but a different lock [%s] is taken out.", perOperationNodeId, existingLockId);
            List<Column> ourExpectedLock = ImmutableList.of(existingColumn);
            CASResult casResult = writeDdlLockWithCas(client, ourExpectedLock, clearedLock);
            if (casResult.isSuccess()) {
                log.info("Successfully released schema mutation lock with id [{}]", SafeArg.of("lockId", existingLockId));
            }
            return casResult.isSuccess();
        });
    } catch (TException e) {
        throw Throwables.throwUncheckedException(e);
    }
}
Also used : TException(org.apache.thrift.TException) Column(org.apache.cassandra.thrift.Column) ColumnOrSuperColumn(org.apache.cassandra.thrift.ColumnOrSuperColumn) CASResult(org.apache.cassandra.thrift.CASResult)

Aggregations

CASResult (org.apache.cassandra.thrift.CASResult)4 FunctionCheckedException (com.palantir.common.base.FunctionCheckedException)2 Column (org.apache.cassandra.thrift.Column)2 TException (org.apache.thrift.TException)2 Cell (com.palantir.atlasdb.keyvalue.api.Cell)1 CheckAndSetException (com.palantir.atlasdb.keyvalue.api.CheckAndSetException)1 CheckAndSetRequest (com.palantir.atlasdb.keyvalue.api.CheckAndSetRequest)1 InsufficientConsistencyException (com.palantir.atlasdb.keyvalue.api.InsufficientConsistencyException)1 KeyAlreadyExistsException (com.palantir.atlasdb.keyvalue.api.KeyAlreadyExistsException)1 PalantirRuntimeException (com.palantir.common.exception.PalantirRuntimeException)1 MultipleRunningTimestampServiceError (com.palantir.timestamp.MultipleRunningTimestampServiceError)1 GuardedBy (javax.annotation.concurrent.GuardedBy)1 ColumnOrSuperColumn (org.apache.cassandra.thrift.ColumnOrSuperColumn)1 NotFoundException (org.apache.cassandra.thrift.NotFoundException)1 UnavailableException (org.apache.cassandra.thrift.UnavailableException)1