private void clearProgressFromCell(SweepProgress progress, Cell cell) { try { CheckAndSetRequest request = CheckAndSetRequest.singleCell( AtlasDbConstants.SWEEP_PROGRESS_TABLE, cell, progressToBytes(progress), FINISHED_TABLE); kvs.checkAndSet(request); } catch (JsonProcessingException e) { log.warn("Exception trying to clear sweep progress. " + "Sweep may continue examining the same range if the problem persists.", e); } }
private CheckAndSetRequest createSingleCellRequest(ShardAndStrategy shardAndStrategy, long oldVal, byte[] colValNew) { byte[] colValOld = createColumnValue(oldVal); return CheckAndSetRequest.singleCell(TABLE_REF, cellForShard(shardAndStrategy), colValOld, colValNew); } }
private CheckAndSetRequest casProgressRequest(Cell cell, Map<Cell, Value> storedProgress, SweepProgress newProgress) throws JsonProcessingException { if (storedProgress.isEmpty()) { // Progress for this thread has never been stored return CheckAndSetRequest.newCell(AtlasDbConstants.SWEEP_PROGRESS_TABLE, cell, progressToBytes(newProgress)); } Value storedValue = Iterables.getOnlyElement(storedProgress.values()); if (isFinishedTablePlaceholder(storedValue)) { // Last iteration, this thread finished a table return CheckAndSetRequest.singleCell(AtlasDbConstants.SWEEP_PROGRESS_TABLE, cell, FINISHED_TABLE, progressToBytes(newProgress)); } else { return CheckAndSetRequest.singleCell(AtlasDbConstants.SWEEP_PROGRESS_TABLE, cell, progressToBytes(hydrateProgress(storedProgress).get()), progressToBytes(newProgress)); } }
@Override public void releaseLock(LockEntry lockEntry) throws CheckAndSetException { CheckAndSetRequest request = CheckAndSetRequest.singleCell(AtlasDbConstants.PERSISTED_LOCKS_TABLE, lockEntry.cell(), lockEntry.value(), LOCK_OPEN.value()); keyValueService.checkAndSet(request); log.info("Successfully released the persistent lock: {}", SafeArg.of("lockEntry", lockEntry)); }
private void updateWatermarkForTable(long newWatermark, TableReference table) { while (true) { Cell cell = cell(table); Optional<Value> currentValue = Optional.ofNullable( kvs.get(CLEARS, ImmutableMap.of(cell, Long.MAX_VALUE)).get(cell)); Optional<Long> currentWatermark = currentValue.map(value -> RowResult.of(cell, value.getContents())) .map(TableClearsRowResult::of) .map(TableClearsRowResult::getLastClearedTimestamp); if (currentWatermark.isPresent() && currentWatermark.get() > newWatermark) { return; } CheckAndSetRequest request = currentWatermark .map(watermark -> CheckAndSetRequest.singleCell( CLEARS, cell, EncodingUtils.encodeVarLong(watermark), EncodingUtils.encodeVarLong(newWatermark))) .orElseGet(() -> CheckAndSetRequest.newCell( CLEARS, cell, EncodingUtils.encodeVarLong(newWatermark))); try { kvs.checkAndSet(request); return; } catch (CheckAndSetException e) { // do nothing, we spin } } }
@Override public LockEntry acquireBackupLock(String reason) throws CheckAndSetException { LockEntry lockEntry = generateUniqueBackupLockEntry(reason); CheckAndSetRequest request = CheckAndSetRequest.singleCell(AtlasDbConstants.PERSISTED_LOCKS_TABLE, lockEntry.cell(), LOCK_OPEN.value(), lockEntry.value()); keyValueService.checkAndSet(request); log.info("Successfully acquired the persistent lock: {}", SafeArg.of("lockEntry", lockEntry)); return lockEntry; }
@Test(expected = CheckAndSetException.class) public void testCheckAndSetFromValueWhenNoValue() { Assume.assumeTrue(checkAndSetSupported()); CheckAndSetRequest request = CheckAndSetRequest.singleCell(TEST_TABLE, TEST_CELL, val(0, 0), val(0, 1)); keyValueService.checkAndSet(request); }
void moveToComplete(TableReference table, int id) { SweepNameToIdRow row = SweepNameToIdRow.of(table.getQualifiedName()); Cell cell = Cell.create(row.persistToBytes(), SweepNameToIdNamedColumn.ID.getShortName()); SweepTableIdentifier oldValue = SweepTableIdentifier.pending(id); SweepTableIdentifier newValue = SweepTableIdentifier.identified(id); CheckAndSetRequest request = CheckAndSetRequest.singleCell( NAME_TO_ID, cell, oldValue.persistToBytes(), newValue.persistToBytes()); try { kvs.checkAndSet(request); } catch (CheckAndSetException e) { SweepTableIdentifier actual = currentMapping(table).get(); checkState(newValue.equals(actual), "Unexpectedly we state changed from pending(id) to " + "not(identified(id)) after identifying id as the correct value"); } }
@Test public void checkAndSet() throws Exception { CheckAndSetRequest request = CheckAndSetRequest.singleCell(TABLE_REF, CELL, ROW_NAME, ROW_NAME); kvs.checkAndSet(request); checkSpan("atlasdb-kvs.checkAndSet({table})"); verify(delegate).checkAndSet(request); verifyNoMoreInteractions(delegate); }
@Test public void testCheckAndSetAndBackAgain() { testCheckAndSetFromOtherValue(); CheckAndSetRequest thirdRequest = CheckAndSetRequest.singleCell(TEST_TABLE, TEST_CELL, val(0, 1), val(0, 0)); keyValueService.checkAndSet(thirdRequest); verifyCheckAndSet(TEST_CELL, val(0, 0)); }
@Test(expected = CheckAndSetException.class) public void testCheckAndSetFromWrongValue() { Assume.assumeTrue(checkAndSetSupported()); CheckAndSetRequest request = CheckAndSetRequest.newCell(TEST_TABLE, TEST_CELL, val(0, 0)); keyValueService.checkAndSet(request); try { CheckAndSetRequest secondRequest = CheckAndSetRequest .singleCell(TEST_TABLE, TEST_CELL, val(0, 1), val(0, 0)); keyValueService.checkAndSet(secondRequest); } catch (CheckAndSetException ex) { assertThat(ex.getActualValues(), contains(val(0, 0))); throw ex; } }
void storeAsPending(TableReference table, int lastAttempt, int thisAttempt) { SweepNameToIdRow row = SweepNameToIdRow.of(table.getQualifiedName()); Cell cell = Cell.create(row.persistToBytes(), SweepNameToIdNamedColumn.ID.getShortName()); byte[] oldValue = SweepTableIdentifier.pending(lastAttempt).persistToBytes(); byte[] newValue = SweepTableIdentifier.pending(thisAttempt).persistToBytes(); CheckAndSetRequest cas = CheckAndSetRequest.singleCell(NAME_TO_ID, cell, oldValue, newValue); try { kvs.checkAndSet(cas); } catch (CheckAndSetException e) { // ignored; we're already spinning } }
@Test public void testCheckAndSetIndependentlyFails() { Assume.assumeTrue(checkAndSetSupported()); Cell firstTestCell = Cell.create(row(0), column(0)); Cell nextTestCell = Cell.create(row(0), column(1)); keyValueService.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, firstTestCell, val(0, 0))); keyValueService.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, nextTestCell, val(0, 1))); assertThatThrownBy(() -> keyValueService.checkAndSet( CheckAndSetRequest.singleCell(TEST_TABLE, nextTestCell, val(0, 0), val(0, 1)))) .isInstanceOf(CheckAndSetException.class); verifyCheckAndSet(firstTestCell, val(0, 0)); verifyCheckAndSet(nextTestCell, val(0, 1)); }
@Test public void testCheckAndSetFromOtherValue() { Assume.assumeTrue(checkAndSetSupported()); CheckAndSetRequest request = CheckAndSetRequest.newCell(TEST_TABLE, TEST_CELL, val(0, 0)); keyValueService.checkAndSet(request); CheckAndSetRequest secondRequest = CheckAndSetRequest.singleCell(TEST_TABLE, TEST_CELL, val(0, 0), val(0, 1)); keyValueService.checkAndSet(secondRequest); verifyCheckAndSet(TEST_CELL, val(0, 1)); }
@Test public void testCheckAndSetIndependentlyWorks() { Assume.assumeTrue(checkAndSetSupported()); Cell firstTestCell = Cell.create(row(0), column(0)); Cell nextTestCell = Cell.create(row(0), column(1)); keyValueService.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, firstTestCell, val(0, 0))); keyValueService.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, nextTestCell, val(0, 1))); keyValueService.checkAndSet(CheckAndSetRequest.singleCell(TEST_TABLE, firstTestCell, val(0, 0), val(0, 1))); verifyCheckAndSet(firstTestCell, val(0, 1)); verifyCheckAndSet(nextTestCell, val(0, 1)); }
private CheckAndSetRequest createSingleCellRequest(ShardAndStrategy shardAndStrategy, long oldVal, byte[] colValNew) { byte[] colValOld = createColumnValue(oldVal); return CheckAndSetRequest.singleCell(TABLE_REF, cellForShard(shardAndStrategy), colValOld, colValNew); } }
@Override public LockEntry acquireBackupLock(String reason) throws CheckAndSetException { LockEntry lockEntry = generateUniqueBackupLockEntry(reason); CheckAndSetRequest request = CheckAndSetRequest.singleCell(AtlasDbConstants.PERSISTED_LOCKS_TABLE, lockEntry.cell(), LOCK_OPEN.value(), lockEntry.value()); keyValueService.checkAndSet(request); log.info("Successfully acquired the persistent lock: {}", SafeArg.of("lockEntry", lockEntry)); return lockEntry; }
@Test public void testCheckAndSetAndBackAgain() { testCheckAndSetFromOtherValue(); CheckAndSetRequest thirdRequest = CheckAndSetRequest.singleCell(TEST_TABLE, TEST_CELL, val(0, 1), val(0, 0)); keyValueService.checkAndSet(thirdRequest); verifyCheckAndSet(TEST_CELL, val(0, 0)); }
@Test public void testCheckAndSetFromOtherValue() { Assume.assumeTrue(checkAndSetSupported()); CheckAndSetRequest request = CheckAndSetRequest.newCell(TEST_TABLE, TEST_CELL, val(0, 0)); keyValueService.checkAndSet(request); CheckAndSetRequest secondRequest = CheckAndSetRequest.singleCell(TEST_TABLE, TEST_CELL, val(0, 0), val(0, 1)); keyValueService.checkAndSet(secondRequest); verifyCheckAndSet(TEST_CELL, val(0, 1)); }
@Test public void testCheckAndSetIndependentlyWorks() { Assume.assumeTrue(checkAndSetSupported()); Cell firstTestCell = Cell.create(row(0), column(0)); Cell nextTestCell = Cell.create(row(0), column(1)); keyValueService.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, firstTestCell, val(0, 0))); keyValueService.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, nextTestCell, val(0, 1))); keyValueService.checkAndSet(CheckAndSetRequest.singleCell(TEST_TABLE, firstTestCell, val(0, 0), val(0, 1))); verifyCheckAndSet(firstTestCell, val(0, 1)); verifyCheckAndSet(nextTestCell, val(0, 1)); }