Skip to content

Fix InterruptedException handling and silently swallowed errors across HDDS and Ozone modules#1

Open
devin-ai-integration[bot] wants to merge 2 commits into
masterfrom
devin/1782584080-fix-error-handling
Open

Fix InterruptedException handling and silently swallowed errors across HDDS and Ozone modules#1
devin-ai-integration[bot] wants to merge 2 commits into
masterfrom
devin/1782584080-fix-error-handling

Conversation

@devin-ai-integration

Copy link
Copy Markdown

What changes were proposed in this pull request?

This PR fixes error handling deficiencies across 16 production source files where InterruptedException is caught without restoring the thread's interrupt status via Thread.currentThread().interrupt(). Per Java concurrency best practices, swallowing the interrupt flag prevents callers higher in the stack from detecting that an interrupt was requested, which can cause threads to hang indefinitely during shutdown or miss cancellation signals.

Additionally, one empty catch block in DefaultCAServer.checkIfKeysExist() that silently discards an IOException is replaced with debug-level logging.

Changes by category

Interrupt status restoration (15 sites across 15 files):

// Before — interrupt flag is lost
} catch (InterruptedException e) {
  LOG.warn("...", e);  // or throw new RuntimeException(e);
}

// After — interrupt flag is preserved for callers
} catch (InterruptedException e) {
  Thread.currentThread().interrupt();
  LOG.warn("...", e);
}

Files fixed:

  • RatisHelper.attemptUntilTrue — split combined InterruptedException | IllegalStateException catch to restore interrupt separately
  • ReconfigurableBase.shutdownReconfigurationTask — restore interrupt on join()
  • LeakDetector.run — restore interrupt before exiting detector loop
  • ContainerCommandResponseBuilders.getEchoResponse — restore interrupt before re-throwing as RuntimeException
  • RocksDBCheckpointDiffer — two sites: pruneOlderCompactionLogs and pruneNonLeafSstFiles, restore interrupt before re-throwing
  • SCMSafeModeManager.startRefresh — restore interrupt in daemon refresh thread
  • OnDemandContainerScanner.scanContainer — restore interrupt on scan interruption
  • AbstractBackgroundContainerScanner.scanContainers — restore interrupt before setting stopping flag
  • StreamBlockInputStream.StreamingReadResponse — two sites: checkError() and setCompleted()
  • GrpcOzoneManagerServer.stop — restore interrupt during gRPC shutdown
  • OzoneManager.EDEKCacheLoader.run — two sites: initial delay and retry sleep
  • OzoneManagerDoubleBuffer.stopDaemon — restore interrupt during daemon join
  • AuthorizerLockImpl — two sites: tryOptimisticReadThrowOnTimeout and tryWriteLockThrowOnTimeout
  • DeleteVolumeHandler.execute — restore interrupt on recursive delete failure
  • SchedulerService.destroy — restore interrupt during scheduler shutdown

Silent error swallowing (1 site):

  • DefaultCAServer.checkIfKeysExist — empty catch (IOException ignored) { } replaced with LOG.debug(...) to aid debugging key-loading failures

What is the link to the Apache JIRA

N/A — this is a fork-local improvement.

How was this patch tested?

Each change is a one-line addition of Thread.currentThread().interrupt() (or a trivial logging addition) with no behavioral change to the surrounding control flow. The changes follow the existing interrupt handling pattern already used correctly elsewhere in the codebase (e.g., BackgroundService.shutdown, SnapshotDiffManager.closeExecutorService, ContainerBalancerTask). Verified via compilation.

Generated-by: Devin (Claude)

Link to Devin session: https://app.devin.ai/sessions/a43e4a35d06b4c6e9a3c88a0638d9288
Requested by: @marcuslin123

…rrors

Restore Thread.currentThread().interrupt() in catch blocks that
swallow InterruptedException without preserving the interrupt status.
Replace an empty catch block in DefaultCAServer with debug logging.

Files changed:
- RatisHelper: split combined catch to restore interrupt separately
- ReconfigurableBase: restore interrupt on shutdown join
- LeakDetector: restore interrupt before exiting loop
- ContainerCommandResponseBuilders: restore interrupt before re-throwing
- RocksDBCheckpointDiffer: restore interrupt before re-throwing (2 sites)
- SCMSafeModeManager: restore interrupt in daemon thread
- OnDemandContainerScanner: restore interrupt on scan interruption
- AbstractBackgroundContainerScanner: restore interrupt on scan interruption
- StreamBlockInputStream: restore interrupt in checkError and setCompleted
- GrpcOzoneManagerServer: restore interrupt during shutdown
- OzoneManager: restore interrupt in EDEKCacheLoader (2 sites)
- OzoneManagerDoubleBuffer: restore interrupt during stopDaemon join
- AuthorizerLockImpl: restore interrupt before wrapping in OMException (2 sites)
- DeleteVolumeHandler: restore interrupt on recursive delete failure
- SchedulerService: restore interrupt during shutdown
- DefaultCAServer: log swallowed IOException at debug level

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@marcuslin123 marcuslin123 self-assigned this Jun 27, 2026
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant