Skip to content

Commit 3d3a1bf

Browse files
Fix potential leaks in search execution
Cleaning up some potentially leaky spots or at the very least making them easier to read.
1 parent b2ebaee commit 3d3a1bf

File tree

2 files changed

+34
-25
lines changed

2 files changed

+34
-25
lines changed

server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java

+33-25
Original file line numberDiff line numberDiff line change
@@ -1303,8 +1303,8 @@ public SearchPhase newSearchPhase(
13031303
task,
13041304
true,
13051305
searchService.getCoordinatorRewriteContextProvider(timeProvider::absoluteStartMillis),
1306-
listener.delegateFailureAndWrap((l, iters) -> {
1307-
SearchPhase action = newSearchPhase(
1306+
listener.delegateFailureAndWrap(
1307+
(l, iters) -> newSearchPhase(
13081308
task,
13091309
searchRequest,
13101310
executor,
@@ -1317,30 +1317,32 @@ public SearchPhase newSearchPhase(
13171317
false,
13181318
threadPool,
13191319
clusters
1320-
);
1321-
action.start();
1322-
})
1323-
);
1324-
} else {
1325-
// for synchronous CCS minimize_roundtrips=false, use the CCSSingleCoordinatorSearchProgressListener
1326-
// (AsyncSearchTask will not return SearchProgressListener.NOOP, since it uses its own progress listener
1327-
// which delegates to CCSSingleCoordinatorSearchProgressListener when minimizing roundtrips)
1328-
if (clusters.isCcsMinimizeRoundtrips() == false
1329-
&& clusters.hasRemoteClusters()
1330-
&& task.getProgressListener() == SearchProgressListener.NOOP) {
1331-
task.setProgressListener(new CCSSingleCoordinatorSearchProgressListener());
1332-
}
1333-
final SearchPhaseResults<SearchPhaseResult> queryResultConsumer = searchPhaseController.newSearchPhaseResults(
1334-
executor,
1335-
circuitBreaker,
1336-
task::isCancelled,
1337-
task.getProgressListener(),
1338-
searchRequest,
1339-
shardIterators.size(),
1340-
exc -> searchTransportService.cancelSearchTask(task, "failed to merge result [" + exc.getMessage() + "]")
1320+
).start()
1321+
)
13411322
);
1323+
}
1324+
// for synchronous CCS minimize_roundtrips=false, use the CCSSingleCoordinatorSearchProgressListener
1325+
// (AsyncSearchTask will not return SearchProgressListener.NOOP, since it uses its own progress listener
1326+
// which delegates to CCSSingleCoordinatorSearchProgressListener when minimizing roundtrips)
1327+
if (clusters.isCcsMinimizeRoundtrips() == false
1328+
&& clusters.hasRemoteClusters()
1329+
&& task.getProgressListener() == SearchProgressListener.NOOP) {
1330+
task.setProgressListener(new CCSSingleCoordinatorSearchProgressListener());
1331+
}
1332+
final SearchPhaseResults<SearchPhaseResult> queryResultConsumer = searchPhaseController.newSearchPhaseResults(
1333+
executor,
1334+
circuitBreaker,
1335+
task::isCancelled,
1336+
task.getProgressListener(),
1337+
searchRequest,
1338+
shardIterators.size(),
1339+
exc -> searchTransportService.cancelSearchTask(task, "failed to merge result [" + exc.getMessage() + "]")
1340+
);
1341+
boolean success = false;
1342+
try {
1343+
final SearchPhase searchPhase;
13421344
if (searchRequest.searchType() == DFS_QUERY_THEN_FETCH) {
1343-
return new SearchDfsQueryThenFetchAsyncAction(
1345+
searchPhase = new SearchDfsQueryThenFetchAsyncAction(
13441346
logger,
13451347
namedWriteableRegistry,
13461348
searchTransportService,
@@ -1359,7 +1361,7 @@ public SearchPhase newSearchPhase(
13591361
);
13601362
} else {
13611363
assert searchRequest.searchType() == QUERY_THEN_FETCH : searchRequest.searchType();
1362-
return new SearchQueryThenFetchAsyncAction(
1364+
searchPhase = new SearchQueryThenFetchAsyncAction(
13631365
logger,
13641366
namedWriteableRegistry,
13651367
searchTransportService,
@@ -1377,6 +1379,12 @@ public SearchPhase newSearchPhase(
13771379
clusters
13781380
);
13791381
}
1382+
success = true;
1383+
return searchPhase;
1384+
} finally {
1385+
if (success == false) {
1386+
queryResultConsumer.close();
1387+
}
13801388
}
13811389
}
13821390
}

server/src/main/java/org/elasticsearch/search/internal/SearchContext.java

+1
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ public Query rewrittenQuery() {
351351
* Adds a releasable that will be freed when this context is closed.
352352
*/
353353
public void addReleasable(Releasable releasable) { // TODO most Releasables are managed by their callers. We probably don't need this.
354+
assert closed.get() == false;
354355
releasables.add(releasable);
355356
}
356357

0 commit comments

Comments
 (0)