@Test public void returnsLockFailureWhenCannotGetLocks() throws InterruptedException { SingleLockService rejectingLockService = mock(SingleLockService.class); when(rejectingLockService.haveLocks()).thenReturn(false); BackgroundCompactor.CompactionOutcome outcome = compactor.grabLockAndRunOnce(rejectingLockService); assertThat(outcome).isEqualTo(BackgroundCompactor.CompactionOutcome.UNABLE_TO_ACQUIRE_LOCKS); }
@VisibleForTesting CompactionOutcome grabLockAndRunOnce(SingleLockService compactorLock) throws InterruptedException { CompactorConfig config = compactorConfigSupplier.get(); if (!config.enableCompaction()) { log.debug("Skipping compaction because it is currently disabled."); return CompactionOutcome.DISABLED; } try { compactorLock.lockOrRefresh(); } catch (Exception e) { log.warn("Encountered exception when attempting to acquire the compaction lock.", e); return CompactionOutcome.UNABLE_TO_ACQUIRE_LOCKS; } if (!compactorLock.haveLocks()) { log.info("Failed to get the compaction lock. Probably, another host is running compaction."); return CompactionOutcome.UNABLE_TO_ACQUIRE_LOCKS; } Optional<String> tableToCompactOptional; try { tableToCompactOptional = compactPriorityCalculator.selectTableToCompact(); } catch (Exception e) { log.warn("Encountered exception when attempting to determine which table should be compacted.", e); return CompactionOutcome.NOTHING_TO_COMPACT; } if (!tableToCompactOptional.isPresent()) { log.debug("No table to compact."); return CompactionOutcome.NOTHING_TO_COMPACT; } String tableToCompact = tableToCompactOptional.get(); try { log.debug("Compacting table {}", LoggingArgs.safeInternalTableName(tableToCompact)); compactTable(tableToCompact, config); log.debug("Compacted table {}", LoggingArgs.safeInternalTableName(tableToCompact)); } catch (Exception e) { log.warn("Encountered exception when compacting table {}", LoggingArgs.safeInternalTableName(tableToCompact), e); return CompactionOutcome.FAILED_TO_COMPACT; } try { registerCompactedTable(tableToCompact); return CompactionOutcome.SUCCESS; } catch (Exception e) { log.debug("Successfully compacted table {}, but failed to register this." + "Nothing bad will happen; we'll probably do a no-op compaction of this very shortly.", LoggingArgs.safeInternalTableName(tableToCompact), e); return CompactionOutcome.COMPACTED_BUT_NOT_REGISTERED; } }
BackgroundCompactor implements AutoCloseable { @VisibleForTesting CompactionOutcome grabLockAndRunOnce(SingleLockService compactorLock) throws InterruptedException { CompactorConfig config = compactorConfigSupplier.get(); if (!config.enableCompaction()) { log.debug("Skipping compaction because it is currently disabled."); return CompactionOutcome.DISABLED; } try { compactorLock.lockOrRefresh(); } catch (Exception e) { log.warn("Encountered exception when attempting to acquire the compaction lock.", e); return CompactionOutcome.UNABLE_TO_ACQUIRE_LOCKS; } if (!compactorLock.haveLocks()) { log.info("Failed to get the compaction lock. Probably, another host is running compaction."); return CompactionOutcome.UNABLE_TO_ACQUIRE_LOCKS; } Optional<String> tableToCompactOptional; try { tableToCompactOptional = compactPriorityCalculator.selectTableToCompact(); } catch (Exception e) { log.warn("Encountered exception when attempting to determine which table should be compacted.", e); return CompactionOutcome.NOTHING_TO_COMPACT; } if (!tableToCompactOptional.isPresent()) { log.debug("No table to compact."); return CompactionOutcome.NOTHING_TO_COMPACT; } String tableToCompact = tableToCompactOptional.get(); try { log.debug("Compacting table {}", LoggingArgs.safeInternalTableName(tableToCompact)); compactTable(tableToCompact, config); log.debug("Compacted table {}", LoggingArgs.safeInternalTableName(tableToCompact)); } catch (Exception e) { log.warn("Encountered exception when compacting table {}", LoggingArgs.safeInternalTableName(tableToCompact), e); return CompactionOutcome.FAILED_TO_COMPACT; } try { registerCompactedTable(tableToCompact); return CompactionOutcome.SUCCESS; } catch (Exception e) { log.debug("Successfully compacted table {}, but failed to register this." + "Nothing bad will happen; we'll probably do a no-op compaction of this very shortly.", LoggingArgs.safeInternalTableName(tableToCompact), e); return CompactionOutcome.COMPACTED_BUT_NOT_REGISTERED; } } }
BackgroundCompactor implements AutoCloseable { @VisibleForTesting CompactionOutcome grabLockAndRunOnce(SingleLockService compactorLock) throws InterruptedException { CompactorConfig config = compactorConfigSupplier.get(); if (!config.enableCompaction()) { log.debug("Skipping compaction because it is currently disabled."); return CompactionOutcome.DISABLED; } try { compactorLock.lockOrRefresh(); } catch (Exception e) { log.warn("Encountered exception when attempting to acquire the compaction lock.", e); return CompactionOutcome.UNABLE_TO_ACQUIRE_LOCKS; } if (!compactorLock.haveLocks()) { log.info("Failed to get the compaction lock. Probably, another host is running compaction."); return CompactionOutcome.UNABLE_TO_ACQUIRE_LOCKS; } Optional<String> tableToCompactOptional; try { tableToCompactOptional = compactPriorityCalculator.selectTableToCompact(); } catch (Exception e) { log.warn("Encountered exception when attempting to determine which table should be compacted.", e); return CompactionOutcome.NOTHING_TO_COMPACT; } if (!tableToCompactOptional.isPresent()) { log.debug("No table to compact."); return CompactionOutcome.NOTHING_TO_COMPACT; } String tableToCompact = tableToCompactOptional.get(); try { log.debug("Compacting table {}", LoggingArgs.safeInternalTableName(tableToCompact)); compactTable(tableToCompact, config); log.debug("Compacted table {}", LoggingArgs.safeInternalTableName(tableToCompact)); } catch (Exception e) { log.warn("Encountered exception when compacting table {}", LoggingArgs.safeInternalTableName(tableToCompact), e); return CompactionOutcome.FAILED_TO_COMPACT; } try { registerCompactedTable(tableToCompact); return CompactionOutcome.SUCCESS; } catch (Exception e) { log.debug("Successfully compacted table {}, but failed to register this." + "Nothing bad will happen; we'll probably do a no-op compaction of this very shortly.", LoggingArgs.safeInternalTableName(tableToCompact), e); return CompactionOutcome.COMPACTED_BUT_NOT_REGISTERED; } } @VisibleForTesting  BackgroundCompactor(
            MetricsManager metricsManager,
            TransactionManager transactionManager,
            KeyValueService keyValueService,
            LockService lockService,
            Supplier<CompactorConfig> compactorConfigSupplier,
            CompactPriorityCalculator compactPriorityCalculator); }
BackgroundCompactor implements AutoCloseable { @VisibleForTesting CompactionOutcome grabLockAndRunOnce(SingleLockService compactorLock) throws InterruptedException { CompactorConfig config = compactorConfigSupplier.get(); if (!config.enableCompaction()) { log.debug("Skipping compaction because it is currently disabled."); return CompactionOutcome.DISABLED; } try { compactorLock.lockOrRefresh(); } catch (Exception e) { log.warn("Encountered exception when attempting to acquire the compaction lock.", e); return CompactionOutcome.UNABLE_TO_ACQUIRE_LOCKS; } if (!compactorLock.haveLocks()) { log.info("Failed to get the compaction lock. Probably, another host is running compaction."); return CompactionOutcome.UNABLE_TO_ACQUIRE_LOCKS; } Optional<String> tableToCompactOptional; try { tableToCompactOptional = compactPriorityCalculator.selectTableToCompact(); } catch (Exception e) { log.warn("Encountered exception when attempting to determine which table should be compacted.", e); return CompactionOutcome.NOTHING_TO_COMPACT; } if (!tableToCompactOptional.isPresent()) { log.debug("No table to compact."); return CompactionOutcome.NOTHING_TO_COMPACT; } String tableToCompact = tableToCompactOptional.get(); try { log.debug("Compacting table {}", LoggingArgs.safeInternalTableName(tableToCompact)); compactTable(tableToCompact, config); log.debug("Compacted table {}", LoggingArgs.safeInternalTableName(tableToCompact)); } catch (Exception e) { log.warn("Encountered exception when compacting table {}", LoggingArgs.safeInternalTableName(tableToCompact), e); return CompactionOutcome.FAILED_TO_COMPACT; } try { registerCompactedTable(tableToCompact); return CompactionOutcome.SUCCESS; } catch (Exception e) { log.debug("Successfully compacted table {}, but failed to register this." + "Nothing bad will happen; we'll probably do a no-op compaction of this very shortly.", LoggingArgs.safeInternalTableName(tableToCompact), e); return CompactionOutcome.COMPACTED_BUT_NOT_REGISTERED; } } @VisibleForTesting  BackgroundCompactor(
            MetricsManager metricsManager,
            TransactionManager transactionManager,
            KeyValueService keyValueService,
            LockService lockService,
            Supplier<CompactorConfig> compactorConfigSupplier,
            CompactPriorityCalculator compactPriorityCalculator); static Optional<BackgroundCompactor> createAndRun(
            MetricsManager metricsManager,
            TransactionManager transactionManager,
            KeyValueService keyValueService,
            LockService lockService,
            Supplier<CompactorConfig> compactorConfigSupplier); @Override void close(); void run(); }
BackgroundCompactor implements AutoCloseable { @VisibleForTesting CompactionOutcome grabLockAndRunOnce(SingleLockService compactorLock) throws InterruptedException { CompactorConfig config = compactorConfigSupplier.get(); if (!config.enableCompaction()) { log.debug("Skipping compaction because it is currently disabled."); return CompactionOutcome.DISABLED; } try { compactorLock.lockOrRefresh(); } catch (Exception e) { log.warn("Encountered exception when attempting to acquire the compaction lock.", e); return CompactionOutcome.UNABLE_TO_ACQUIRE_LOCKS; } if (!compactorLock.haveLocks()) { log.info("Failed to get the compaction lock. Probably, another host is running compaction."); return CompactionOutcome.UNABLE_TO_ACQUIRE_LOCKS; } Optional<String> tableToCompactOptional; try { tableToCompactOptional = compactPriorityCalculator.selectTableToCompact(); } catch (Exception e) { log.warn("Encountered exception when attempting to determine which table should be compacted.", e); return CompactionOutcome.NOTHING_TO_COMPACT; } if (!tableToCompactOptional.isPresent()) { log.debug("No table to compact."); return CompactionOutcome.NOTHING_TO_COMPACT; } String tableToCompact = tableToCompactOptional.get(); try { log.debug("Compacting table {}", LoggingArgs.safeInternalTableName(tableToCompact)); compactTable(tableToCompact, config); log.debug("Compacted table {}", LoggingArgs.safeInternalTableName(tableToCompact)); } catch (Exception e) { log.warn("Encountered exception when compacting table {}", LoggingArgs.safeInternalTableName(tableToCompact), e); return CompactionOutcome.FAILED_TO_COMPACT; } try { registerCompactedTable(tableToCompact); return CompactionOutcome.SUCCESS; } catch (Exception e) { log.debug("Successfully compacted table {}, but failed to register this." + "Nothing bad will happen; we'll probably do a no-op compaction of this very shortly.", LoggingArgs.safeInternalTableName(tableToCompact), e); return CompactionOutcome.COMPACTED_BUT_NOT_REGISTERED; } } @VisibleForTesting  BackgroundCompactor(
            MetricsManager metricsManager,
            TransactionManager transactionManager,
            KeyValueService keyValueService,
            LockService lockService,
            Supplier<CompactorConfig> compactorConfigSupplier,
            CompactPriorityCalculator compactPriorityCalculator); static Optional<BackgroundCompactor> createAndRun(
            MetricsManager metricsManager,
            TransactionManager transactionManager,
            KeyValueService keyValueService,
            LockService lockService,
            Supplier<CompactorConfig> compactorConfigSupplier); @Override void close(); void run(); static final long SLEEP_TIME_WHEN_NOTHING_TO_COMPACT_MIN_MILLIS; }