@Override public void checkAndSet(CheckAndSetRequest checkAndSetRequest) { delegate1.checkAndSet(checkAndSetRequest); }
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); } }
@Test(expected = CheckAndSetException.class) public void testCheckAndSetFromNoValueWhenValueIsPresent() { Assume.assumeTrue(checkAndSetSupported()); CheckAndSetRequest request = CheckAndSetRequest.newCell(TEST_TABLE, TEST_CELL, val(0, 0)); keyValueService.checkAndSet(request); keyValueService.checkAndSet(request); }
@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)); }
@Override public void saveProgress(SweepProgress newProgress) { Cell cell = getCell(newProgress.tableRef()); Map<Cell, Value> entry = getStoredProgress(newProgress.tableRef()); try { kvs.checkAndSet(casProgressRequest(cell, entry, newProgress)); } catch (Exception e) { log.warn("Exception trying to persist sweep progress. The intermediate progress might not have been " + "persisted. This should not cause sweep issues unless the problem persists.", e); } }
@Override public void checkAndSet(CheckAndSetRequest checkAndSetRequest) throws CheckAndSetException { //noinspection unused - try-with-resources closes trace try (CloseableTrace trace = startLocalTrace("checkAndSet({})", LoggingArgs.safeTableOrPlaceholder(checkAndSetRequest.table()))) { delegate().checkAndSet(checkAndSetRequest); } }
@Override public void checkAndSet(CheckAndSetRequest request) { maybeLog(() -> delegate.checkAndSet(request), logCellsAndSize("checkAndSet", request.table(), 1, request.newValue().length)); }
@Test public void testReadFromOldProgress() throws JsonProcessingException { byte[] progressBytes = SweepProgressStoreImpl.progressToBytes(PROGRESS); kvs.checkAndSet(CheckAndSetRequest.newCell(AtlasDbConstants.SWEEP_PROGRESS_TABLE, SweepProgressStoreImpl.LEGACY_CELL, progressBytes)); // Enforce initialisation, which is where we expect the legacy value to be read. SweepProgressStore newProgressStore = SweepProgressStoreImpl.create(kvs, false); Assert.assertEquals(Optional.of(PROGRESS), newProgressStore.loadProgress(TABLE)); }
@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 progressivelyFailingCasEventuallySucceeds() { KeyValueService mockKvs = mock(KeyValueService.class); when(mockKvs.get(any(), anyMap())) .thenReturn(ImmutableMap.of()) .thenReturn(ImmutableMap.of(DUMMY, createValue(5L))) .thenReturn(ImmutableMap.of(DUMMY, createValue(10L))) .thenReturn(ImmutableMap.of(DUMMY, createValue(15L))); doThrow(new CheckAndSetException("sadness")).when(mockKvs).checkAndSet(any()); ShardProgress instrumentedProgress = new ShardProgress(mockKvs); assertThat(instrumentedProgress.updateLastSweptTimestamp(CONSERVATIVE_TEN, 12L)) .isEqualTo(15L); }
@Test public void testCheckAndSetLargeValue() { Assume.assumeTrue(checkAndSetSupported()); byte[] megabyteValue = new byte[1048576]; CheckAndSetRequest request = CheckAndSetRequest.newCell(TEST_TABLE, TEST_CELL, megabyteValue); keyValueService.checkAndSet(request); verifyCheckAndSet(TEST_CELL, megabyteValue); }
@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(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); }
boolean storeNewMapping(TableReference table, int id) { SweepIdToNameColumn column = SweepIdToNameColumn.of(id); SweepIdToNameColumnValue value = SweepIdToNameColumnValue.of(column, table.getQualifiedName()); Cell cell = Cell.create(rowAsBytes, value.persistColumnName()); CheckAndSetRequest request = CheckAndSetRequest.newCell(ID_TO_NAME, cell, value.persistValue()); try { kvs.checkAndSet(request); return true; } catch (CheckAndSetException e) { return get(id).get().equals(table); } }
@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)); }
@Test public void testCheckAndSetFromEmpty() { Assume.assumeTrue(checkAndSetSupported()); CheckAndSetRequest request = CheckAndSetRequest.newCell(TEST_TABLE, TEST_CELL, val(0, 0)); keyValueService.checkAndSet(request); verifyCheckAndSet(TEST_CELL, val(0, 0)); }
@Test public void canUpgradeNumberOfShardsIfPersistedDefaultValue() { byte[] defaultValue = ShardProgress.createColumnValue(AtlasDbConstants.DEFAULT_SWEEP_QUEUE_SHARDS); CheckAndSetRequest request = progress.createNewCellRequest(ShardProgress.SHARD_COUNT_SAS, defaultValue); kvs.checkAndSet(request); progress.updateNumberOfShards(128); assertThat(progress.getNumberOfShards()).isEqualTo(128); }
@Test public void testCheckAndSetToNewCellsInDistinctRows() { 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))); verifyCheckAndSet(firstTestCell, val(0, 0)); verifyCheckAndSet(nextTestCell, val(0, 1)); }
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 fromRowResultProducesLockEntry() { KeyValueService kvs = new InMemoryKeyValueService(false); kvs.createTable(TEST_TABLE, AtlasDbConstants.GENERIC_TABLE_METADATA); kvs.checkAndSet(CheckAndSetRequest.newCell(TEST_TABLE, LOCK_ENTRY.cell(), LOCK_ENTRY.value())); Iterator<RowResult<Value>> range = kvs.getRange(TEST_TABLE, RangeRequest.all(), AtlasDbConstants.TRANSACTION_TS + 1); RowResult<Value> onlyEntry = Iterables.getOnlyElement(ImmutableSet.copyOf(range)); LockEntry lockEntry = LockEntry.fromRowResult(onlyEntry); assertEquals(LOCK_ENTRY, lockEntry); }