use of com.palantir.lock.LockService in project atlasdb by palantir.
the class SnapshotTransactionTest method testTransactionAtomicity.
@Test
public void testTransactionAtomicity() throws Exception {
// This test runs multiple transactions in parallel, with KeyValueService.put calls throwing
// a RuntimeException from time to time and hanging other times. which effectively kills the
// thread. We ensure that every transaction either adds 5 rows to the table or adds 0 rows
// by checking at the end that the number of rows is a multiple of 5.
final TableReference tableRef = TABLE;
Random random = new Random(1);
final UnstableKeyValueService unstableKvs = new UnstableKeyValueService(keyValueService, random);
final TestTransactionManager unstableTransactionManager = new TestTransactionManagerImpl(unstableKvs, timestampService, lockClient, lockService, transactionService, conflictDetectionManager, sweepStrategyManager, sweepQueue);
ScheduledExecutorService service = PTExecutors.newScheduledThreadPool(20);
for (int i = 0; i < 30; i++) {
final int threadNumber = i;
service.schedule((Callable<Void>) () -> {
if (threadNumber == 10) {
unstableKvs.setRandomlyThrow(true);
}
if (threadNumber == 20) {
unstableKvs.setRandomlyHang(true);
}
Transaction transaction = unstableTransactionManager.createNewTransaction();
BatchingVisitable<RowResult<byte[]>> results = transaction.getRange(tableRef, RangeRequest.builder().build());
final MutableInt nextIndex = new MutableInt(0);
results.batchAccept(1, AbortingVisitors.batching((AbortingVisitor<RowResult<byte[]>, Exception>) row -> {
byte[] dataBytes = row.getColumns().get(PtBytes.toBytes("data"));
BigInteger dataValue = new BigInteger(dataBytes);
nextIndex.setValue(Math.max(nextIndex.toInteger(), dataValue.intValue() + 1));
return true;
}));
// rows to the table.
for (int j = 0; j < 5; j++) {
int rowNumber = nextIndex.toInteger() + j;
Cell cell = Cell.create(PtBytes.toBytes("row" + rowNumber), PtBytes.toBytes("data"));
transaction.put(tableRef, ImmutableMap.of(cell, BigInteger.valueOf(rowNumber).toByteArray()));
Thread.yield();
}
transaction.commit();
return null;
}, i * 20, TimeUnit.MILLISECONDS);
}
service.shutdown();
service.awaitTermination(1, TimeUnit.SECONDS);
// Verify each table has a number of rows that's a multiple of 5
Transaction verifyTransaction = txManager.createNewTransaction();
BatchingVisitable<RowResult<byte[]>> results = verifyTransaction.getRange(tableRef, RangeRequest.builder().build());
final MutableInt numRows = new MutableInt(0);
results.batchAccept(1, AbortingVisitors.batching((AbortingVisitor<RowResult<byte[]>, Exception>) row -> {
numRows.increment();
return true;
}));
Assert.assertEquals(0, numRows.toInteger() % 5);
}
use of com.palantir.lock.LockService in project atlasdb by palantir.
the class TransactionManagerTest method shouldNotConflictIfImmutableTimestampLockExpiresEvenIfNoWritesOnNonThoroughSweptTable.
@Test
public void shouldNotConflictIfImmutableTimestampLockExpiresEvenIfNoWritesOnNonThoroughSweptTable() {
TimelockService timelock = mock(TimelockService.class);
LockService mockLockService = mock(LockService.class);
TransactionManager txnManagerWithMocks = new SerializableTransactionManager(keyValueService, timelock, mockLockService, transactionService, () -> AtlasDbConstraintCheckingMode.FULL_CONSTRAINT_CHECKING_THROWS_EXCEPTIONS, conflictDetectionManager, sweepStrategyManager, NoOpCleaner.INSTANCE, TimestampTrackerImpl.createNoOpTracker(), () -> AtlasDbConstants.DEFAULT_TIMESTAMP_CACHE_SIZE, false, () -> AtlasDbConstants.DEFAULT_TRANSACTION_LOCK_ACQUIRE_TIMEOUT_MS, AbstractTransactionTest.GET_RANGES_THREAD_POOL_SIZE, AbstractTransactionTest.DEFAULT_GET_RANGES_CONCURRENCY, MultiTableSweepQueueWriter.NO_OP);
when(timelock.getFreshTimestamp()).thenReturn(1L);
when(timelock.lockImmutableTimestamp(any())).thenReturn(LockImmutableTimestampResponse.of(2L, LockToken.of(UUID.randomUUID())));
txnManagerWithMocks.runTaskThrowOnConflict(txn -> {
get(txn, TEST_TABLE, "row1", "col1");
return null;
});
}
use of com.palantir.lock.LockService in project atlasdb by palantir.
the class TimeLockAgent method createInvalidatingTimeLockServices.
/**
* Creates timestamp and lock services for the given client. It is expected that for each client there should
* only be (up to) one active timestamp service, and one active lock service at any time.
* @param client Client namespace to create the services for
* @return Invalidating timestamp and lock services
*/
private TimeLockServices createInvalidatingTimeLockServices(String client) {
List<String> uris = install.cluster().clusterMembers();
ImmutableLeaderConfig leaderConfig = ImmutableLeaderConfig.builder().addLeaders(uris.toArray(new String[uris.size()])).localServer(install.cluster().localServer()).sslConfiguration(PaxosRemotingUtils.getSslConfigurationOptional(install)).quorumSize(PaxosRemotingUtils.getQuorumSize(uris)).build();
Supplier<ManagedTimestampService> rawTimestampServiceSupplier = timestampCreator.createTimestampService(client, leaderConfig);
Supplier<LockService> rawLockServiceSupplier = lockCreator::createThreadPoolingLockService;
LockLog.setSlowLockThresholdMillis(JavaSuppliers.compose(TimeLockRuntimeConfiguration::slowLockLogTriggerMillis, runtime));
return timelockCreator.createTimeLockServices(client, rawTimestampServiceSupplier, rawLockServiceSupplier);
}
use of com.palantir.lock.LockService in project atlasdb by palantir.
the class LegacyTimeLockServicesCreator method createTimeLockServices.
@Override
public TimeLockServices createTimeLockServices(String client, Supplier<ManagedTimestampService> rawTimestampServiceSupplier, Supplier<LockService> rawLockServiceSupplier) {
log.info("Creating legacy timelock service for client {}", client);
ManagedTimestampService timestampService = instrumentInLeadershipProxy(ManagedTimestampService.class, rawTimestampServiceSupplier, client);
LockService lockService = instrumentInLeadershipProxy(LockService.class, rawLockServiceSupplier, client);
// The underlying primitives are already wrapped in a leadership proxy (and must be).
// Wrapping this means that we will make 2 paxos checks per request, which is silly.
TimelockService legacyTimelockService = instrument(TimelockService.class, createRawLegacyTimelockService(timestampService, lockService), client);
return TimeLockServices.create(timestampService, lockService, AsyncOrLegacyTimelockService.createFromLegacyTimelock(legacyTimelockService), timestampService);
}
use of com.palantir.lock.LockService in project atlasdb by palantir.
the class PaxosTimeLockServerIntegrationTest method lockServiceShouldNotAllowUsToRefreshLocksFromDifferentNamespaces.
@Test
public void lockServiceShouldNotAllowUsToRefreshLocksFromDifferentNamespaces() throws InterruptedException {
LockService lockService1 = getLockService(CLIENT_1);
LockService lockService2 = getLockService(CLIENT_2);
LockRefreshToken token = lockService1.lock(LOCK_CLIENT_NAME, com.palantir.lock.LockRequest.builder(LOCK_MAP).doNotBlock().build());
assertThat(token).isNotNull();
assertThat(lockService1.refreshLockRefreshTokens(ImmutableList.of(token))).isNotEmpty();
assertThat(lockService2.refreshLockRefreshTokens(ImmutableList.of(token))).isEmpty();
lockService1.unlock(token);
}
Aggregations