|
16 | 16 | import org.elasticsearch.cluster.node.DiscoveryNode; |
17 | 17 | import org.elasticsearch.cluster.service.ClusterService; |
18 | 18 | import org.elasticsearch.common.util.concurrent.EsExecutors; |
| 19 | +import org.elasticsearch.compute.EsqlRefCountingListener; |
19 | 20 | import org.elasticsearch.compute.data.BlockFactory; |
20 | 21 | import org.elasticsearch.compute.operator.exchange.ExchangeService; |
21 | 22 | import org.elasticsearch.core.TimeValue; |
|
36 | 37 |
|
37 | 38 | import java.io.IOException; |
38 | 39 | import java.util.concurrent.TimeUnit; |
| 40 | +import java.util.concurrent.atomic.AtomicReference; |
39 | 41 |
|
40 | 42 | import static org.elasticsearch.xpack.core.ClientHelper.ASYNC_SEARCH_ORIGIN; |
41 | 43 |
|
@@ -123,7 +125,15 @@ private void stopQueryAndReturnResult(Task task, AsyncExecutionId asyncId, Actio |
123 | 125 | } catch (IOException e) { |
124 | 126 | throw new ResourceNotFoundException(asyncId + " not found", e); |
125 | 127 | } |
126 | | - asyncListener.addListener(listener); |
127 | | - exchangeService.finishSessionEarly(sessionID(asyncId), ActionListener.noop()); |
| 128 | + // Here we will wait for both the response to become available and for the finish operation to complete |
| 129 | + var responseHolder = new AtomicReference<EsqlQueryResponse>(); |
| 130 | + ActionListener<Void> resultListener = listener.delegateFailureIgnoreResponseAndWrap(l -> l.onResponse(responseHolder.get())); |
| 131 | + try (var refs = new EsqlRefCountingListener(resultListener)) { |
| 132 | + asyncListener.addListener(refs.acquire().map(r -> { |
| 133 | + responseHolder.set(r); |
| 134 | + return null; |
| 135 | + })); |
| 136 | + exchangeService.finishSessionEarly(sessionID(asyncId), refs.acquire()); |
| 137 | + } |
128 | 138 | } |
129 | 139 | } |
0 commit comments