Repository navigation
Conversation
…s a RuntimeException PeriodicalTask#run called getTasks() outside any try/catch. Since the task is scheduled with scheduleWithFixedDelay, an exception escaping run() silently cancels all later executions. For example DirectoryDeletingService#getTasks iterates the snapshot chain, and a concurrent snapshot purge makes the iterator throw NoSuchElementException, after which the service never runs again on that OM. Catch RuntimeException from getTasks(), log it and retry in the next interval. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
2 open findings
What changed in this PR
Prevents BackgroundService periodic execution from being permanently cancelled when getTasks() throws at runtime, which previously caused background services to stop silently and led to test timeouts.
Changes:
- Catch and log
RuntimeExceptionfromBackgroundService.PeriodicalTask#runwhen callinggetTasks(), then return to allow the next scheduled interval to proceed. - Add a regression test ensuring the service continues running after an initial
getTasks()failure.
| File | Description |
|---|---|
| hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/BackgroundService.java | Wraps getTasks() in try/catch to prevent scheduled task cancellation on runtime exceptions. |
| hadoop-hdds/framework/src/test/java/org/apache/hadoop/util/TestBackgroundService.java | Adds a test verifying periodic scheduling continues after getTasks() throws once. |
🧠 Review effort: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
jojochuang
left a comment
There was a problem hiding this comment.
Approve. Catching RuntimeException from getTasks() in PeriodicalTask.run() is the right framework-level fix: scheduleWithFixedDelay stops scheduling after an uncaught throw, which matches the DDS outage when snapshot-chain iteration failed mid-getTasks.
The unit test cleanly proves the schedule survives a failed first getTasks() cycle. This is defense in depth alongside HDDS-16954 (#11500), which fixes the iterator race itself—both should land.
priyeshkaratha
left a comment
There was a problem hiding this comment.
Thanks for the patch @smengcl and changes LGTM


Generated-by: Claude Code (Sonnet 5.5)
What changes were proposed in this pull request?
BackgroundService.PeriodicalTask#runcalledgetTasks()outside any try/catch. The task is scheduled withscheduleWithFixedDelay, which silently cancels all later executions when a run throws.DirectoryDeletingService#getTasksiterates the snapshot chain without a lock, so a concurrent snapshot purge makes the iterator throwNoSuchElementException, and the service then never runs again on that OM. This is what madeTestSnapshotDeletingServiceIntegrationTest#testSnapshotWithFSOtime out waiting for deep cleaning.This patch catches
RuntimeExceptionfromgetTasks(), logs it and retries in the next interval, so one bad cycle cannot cancel the schedule of any background service. Making the snapshot chain iteration itself race safe is left as a follow up.What is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-16949
How was this patch tested?
Added
TestBackgroundService#testServiceKeepsRunningAfterGetTasksThrows, wheregetTasks()throws on the first call. It fails with a timeout without the fix and passes with it.TestBackgroundService(3 tests) and checkstyle pass locally.🤖 Generated with Claude Code