Skip to content

HDDS-16398. Fix intermittent AlreadyClosedException in TestCommitWatcher - #11227

Open
yandrey321 wants to merge 1 commit into
apache:masterfrom
yandrey321:HDDS-16398
Open

HDDS-16398. Fix intermittent AlreadyClosedException in TestCommitWatcher#11227
yandrey321 wants to merge 1 commit into
apache:masterfrom
yandrey321:HDDS-16398

Conversation

@yandrey321

@yandrey321 yandrey321 commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

TestCommitWatcher#testReleaseBuffersOnException (and testReleaseBuffers, which shares the same setup) intermittently fail because the test starts writing to a freshly-allocated RATIS THREE pipeline before that pipeline's Ratis group has elected a leader.

@beforeeach calls cluster.waitForClusterToBeReady(), which waits only for datanode registration and SCM readiness — not for the pipeline's leader election. When the first putBlock/watch lands before a leader is settled, Ratis returns NotLeaderException; under the test's deliberately short (3s) request/watch timeouts the retries are exhausted and the client is closed, surfacing as:

NotLeaderException
-> RaftRetryFailureException
-> AlreadyClosedException: SlidingWindow$Client:client-...->RAFT is closed.
The failure occurs at future1.get() during setup, before the test reaches the datanode-shutdown scenario it actually exercises.

The fix adds one call in @beforeeach, after the cluster is ready, to wait for the RATIS THREE pipeline to reach OPEN before any writes:

cluster.waitForClusterToBeReady();
// Wait for the RATIS THREE pipeline to reach OPEN state before any writes.
// A pipeline only opens once it is healthy, which requires an elected Ratis
// leader; otherwise the first write can race leader election and fail with
// NotLeaderException -> RaftRetryFailureException -> AlreadyClosedException.
cluster.waitForPipelineTobeReady(HddsProtos.ReplicationFactor.THREE, 60000);
This closes the race deterministically: SCM transitions a RATIS pipeline to OPEN only when Pipeline.isHealthy() is true, and for a RATIS pipeline isHealthy() requires all datanodes to have reported and leaderId != null. So once the pipeline is OPEN, a leader has been elected and reported — exactly the precondition the writes depend on. The change reuses the existing MiniOzoneCluster.waitForPipelineTobeReady(...) helper (no new abstraction) and, being in @beforeeach, protects both tests in the class.

This is a test-only change; no production code is affected.

Generated-by: Claude Code (Claude Opus 4.8)

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-16398

How was this patch tested?

CI: https://github.com/yandrey321/ozone/actions/runs/34411454199/job/102906678997

@chihsuan chihsuan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this flaky test! @yandrey321 Could you share the CI log of the failure you investigated? The Jira stack trace is truncated.

Would it also be worth running the intermittent-test-check workflow on your branch to confirm it's stable?

Small nit: the code snippets in the description could use ``` fences so they render properly. Thanks!

@yandrey321

Copy link
Copy Markdown
Contributor Author

Thanks for looking into this flaky test! @yandrey321 Could you share the CI log of the failure you investigated? The Jira stack trace is truncated.

Would it also be worth running the intermittent-test-check workflow on your branch to confirm it's stable?

Small nit: the code snippets in the description could use ``` fences so they render properly. Thanks!

here is the link to the failed CI: https://github.com/yandrey321/ozone/actions/runs/34395742534/job/102619847831

I saw multiple CI runs with the same signature.

@chihsuan chihsuan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here is the link to the failed CI: https://github.com/yandrey321/ozone/actions/runs/34395742534/job/102619847831

Thanks for the link! @yandrey321 I ran the intermittent-test-check on your branch and it still failed 3 times: https://github.com/chihsuan/ozone/actions/runs/34612123189

The failures have different signatures, so I suspect the root cause is different and there may be multiple issues. Could you take a look?

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.

2 participants