From a02ca76edd017a626dea9b529cfe0e3bf316a981 Mon Sep 17 00:00:00 2001 From: Jeremy Dahlgren Date: Fri, 13 Jun 2025 12:06:14 -0400 Subject: [PATCH] Fix RestCancellableNodeClientTests.testConcurrentExecuteAndClose() (#129294) Fixes a race condition in testConcurrentExecuteAndClose() where awaitClose() is called before addCloseListener() has been called, resulting in a situation where closeListener is never completed and the closeLatch is never pulled. Closes #129121 (cherry picked from commit 9a8e50375c0f07d72eda4517fde5ddc7371a4b65) --- .../rest/action/RestCancellableNodeClientTests.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/src/test/java/org/elasticsearch/rest/action/RestCancellableNodeClientTests.java b/server/src/test/java/org/elasticsearch/rest/action/RestCancellableNodeClientTests.java index 4f880ddc92820..7111c52124739 100644 --- a/server/src/test/java/org/elasticsearch/rest/action/RestCancellableNodeClientTests.java +++ b/server/src/test/java/org/elasticsearch/rest/action/RestCancellableNodeClientTests.java @@ -303,6 +303,11 @@ public void addCloseListener(ActionListener listener) { // if the channel is already closed, the listener gets notified immediately, from the same thread. if (open.get() == false) { listener.onResponse(null); + // Ensure closeLatch is pulled by completing the closeListener with a noop that is ignored if it is already completed. + // Note that when the channel is closed we may see multiple addCloseListener() calls, so we do not assert on isDone() here, + // and since closeListener may already be completed we cannot rely on it to complete the current listener, so we first + // complete it directly and then pass a noop to closeListener. + closeListener.onResponse(ActionListener.assertOnce(ActionListener.noop())); } else { if (closeListener.compareAndSet(null, listener) == false) { throw new AssertionError("close listener already set, only one is allowed!");