use of com.palantir.timestamp.MultipleRunningTimestampServiceError in project atlasdb by palantir.
the class CassandraTimestampIntegrationTest method testMultipleThrows.
@Test
public void testMultipleThrows() {
TimestampBoundStore ts = CassandraTimestampBoundStore.create(kv);
TimestampBoundStore ts2 = CassandraTimestampBoundStore.create(kv);
long limit = ts.getUpperLimit();
Assert.assertEquals(limit, ts2.getUpperLimit());
ts.storeUpperLimit(limit + 10);
Assert.assertEquals(limit + 10, ts.getUpperLimit());
Assert.assertEquals(limit + 10, ts2.getUpperLimit());
ts.storeUpperLimit(limit + 20);
try {
ts2.storeUpperLimit(limit + 20);
Assert.fail();
} catch (MultipleRunningTimestampServiceError e) {
// expected
}
Assert.assertEquals(limit + 20, ts.getUpperLimit());
Assert.assertEquals(limit + 20, ts2.getUpperLimit());
ts.storeUpperLimit(limit + 30);
Assert.assertEquals(limit + 30, ts.getUpperLimit());
try {
ts2.storeUpperLimit(limit + 40);
Assert.fail();
} catch (MultipleRunningTimestampServiceError e) {
// expected
}
}
use of com.palantir.timestamp.MultipleRunningTimestampServiceError in project atlasdb by palantir.
the class CassandraTimestampStoreInvalidatorIntegrationTest method invalidationDuringTimestampIssuanceYieldsConsistentResults.
/**
* Consistent results here mean that:
* (1) all calls to backupAndInvalidate() return the same value V, and
* (2) this value V is the maximum of all successfully stored timestamp bounds.
*/
@Test
public void invalidationDuringTimestampIssuanceYieldsConsistentResults() {
Set<Long> backedUpValues = Sets.newConcurrentHashSet();
AtomicLong maxSuccessfulBound = new AtomicLong(CassandraTimestampUtils.INITIAL_VALUE);
CassandraTestTools.executeInParallelOnExecutorService(() -> {
CassandraTimestampStoreInvalidator storeInvalidator = CassandraTimestampStoreInvalidator.create(kv);
try {
if (ThreadLocalRandom.current().nextBoolean()) {
backedUpValues.add(storeInvalidator.backupAndInvalidate());
} else {
maxSuccessfulBound.accumulateAndGet(getBoundAfterTakingOutOneMillionTimestamps(), Math::max);
}
} catch (IllegalArgumentException | IllegalStateException | MultipleRunningTimestampServiceError error) {
// Can arise if trying to manipulate the timestamp bound during/after an invalidation. This is fine.
}
});
if (!backedUpValues.isEmpty()) {
invalidator.revalidateFromBackup();
assertThat(Iterables.getOnlyElement(backedUpValues)).isEqualTo(maxSuccessfulBound.get());
assertWeCanReadTimestamp(maxSuccessfulBound.get());
}
// 2^-32 chance that nothing got backed up; accept in this case.
}
use of com.palantir.timestamp.MultipleRunningTimestampServiceError 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;
}
}
Aggregations