Source:
<code>public void run() { isRunning = true; startLatch.countDown(); try { logger.info("Starting compaction thread"); for (BlobStore store : stores) { logger.trace("{} being checked for resume", store); if (store.isStarted()) { logger.trace("{} is started and eligible for resume check", store); try { metrics.markCompactionStart(false); store.maybeResumeCompaction(); metrics.markCompactionStop(); } catch (Exception e) { metrics.compactionErrorCount.inc(); logger.error("Compaction of store failed on resume. Continuing with the next store", store, e); storesToSkip.add(store); } } } while (enabled) { try { long startTimeMs = time.milliseconds(); for (BlobStore store : stores) { logger.trace("{} being checked for compaction", store); try { if (!enabled) { logger.trace("Breaking out because compaction thread is disabled"); break; } if (store.isStarted() && !storesToSkip.contains(store)) { logger.trace("{} is started and eligible for compaction check", store); CompactionDetails details = getCompactionDetails(store); if (details != null) { logger.trace("Generated as details for {}", details, store); metrics.markCompactionStart(true); store.compact(details); <START> metrics.markCompactionStop(); <END> } } } catch (Exception e) { metrics.compactionErrorCount.inc(); logger.error("Compaction of store failed. Continuing with the next store", store, e); storesToSkip.add(store); } } lock.lock(); try { if (enabled) { long timeElapsed = time.milliseconds() - startTimeMs; logger.trace("Going to wait for ms", waitTimeMs - timeElapsed); time.await(waitCondition, waitTimeMs - timeElapsed); } } finally { lock.unlock(); } } catch (Exception e) { metrics.compactionExecutorErrorCount.inc(); logger.error("Compaction executor encountered an error. Continuing", e); } } } finally { isRunning = false; logger.info("Stopping compaction thread"); } }</code><technical_language>please double check marking end of done in right place (that is, do in finally if want cover exit paths)</technical_language>

Target:
public void run() { isRunning = true; try { logger.info("Starting compaction thread for {}", mountPath); for (BlobStore store : stores) { logger.trace("{} being checked for resume", store); if (store.isStarted()) { logger.trace("{} is started and eligible for resume check", store); metrics.markCompactionStart(false); try { store.maybeResumeCompaction(); } catch (Exception e) { metrics.compactionErrorCount.inc(); logger.error("Compaction of store failed on resume. Continuing with the next store", store, e); storesToSkip.add(store); } finally { metrics.markCompactionStop(); } } } while (enabled) { try { long startTimeMs = time.milliseconds(); for (BlobStore store : stores) { logger.trace("{} being checked for compaction", store); try { if (!enabled) { logger.trace("Breaking out because compaction thread is disabled for {}", mountPath); break; } if (store.isStarted() && !storesToSkip.contains(store)) { logger.trace("{} is started and eligible for compaction check", store); CompactionDetails details = getCompactionDetails(store); if (details != null) { logger.trace("Generated as details for {}", details, store); metrics.markCompactionStart(true); store.compact(details); metrics.markCompactionStop(); } } } catch (Exception e) { metrics.compactionErrorCount.inc(); logger.error("Compaction of store failed. Continuing with the next store", store, e); storesToSkip.add(store); } } lock.lock(); try { if (enabled) { long timeElapsed = time.milliseconds() - startTimeMs; logger.trace("Going to wait for ms in compaction thread at {}", waitTimeMs - timeElapsed, mountPath); time.await(waitCondition, waitTimeMs - timeElapsed); } } finally { lock.unlock(); } } catch (Exception e) { metrics.compactionExecutorErrorCount.inc(); logger.error("Compaction executor for encountered an error. Continuing", mountPath, e); } } } finally { isRunning = false; logger.info("Stopping compaction thread for {}", mountPath); } }