`org.elasticsearch.action.search.AbstractSearchAsyncAction#clusterState` is almost entirely unused, except for one trace log message and one call to `org.elasticsearch.cluster.ClusterState#getMinTransportVersion`. If the cluster state is changing quickly while searches are starting then these captured cluster states can consume substantial memory. If all we care about is the min transport version then we should just pass that in.

Note that the cluster state that ends up here is also captured by various lambdas (e.g. the one that runs after the can-match phase). The more we can reduce the scope of this cluster state capture, the better.
server/src/main/java/org/elasticsearch/action/search/AbstractSearchAsyncAction.java
shardIt.getSearchContextKeepAlive()
        );
        
        
        
        
        shardRequest.canReturnNullResponseIfMatchNoDocs(hasShardResponse.get() && shardRequest.scroll() == null);
        return shardRequest;
    }
    /**
     * Returns the next phase based on the results of the initial search phase
     * @param results the results of the initial search phase. Each non null element in the result array represent a successfully
     *                executed shard request
     * @param context the search context for the next phase
     */
    protected abstract SearchPhase getNextPhase(SearchPhaseResults<Result> results, SearchPhaseContext context);
    private void executeNext(PendingExecutions pendingExecutions, Thread originalThread) {
        executeNext(pendingExecutions == null ? null : pendingExecutions.finishAndGetNext(), originalThread);
    }
    void executeNext(Runnable runnable, Thread originalThread) {
        if (runnable != null) {
            assert throttleConcurrentRequests;
            if (originalThread == Thread.currentThread()) {
                fork(runnable);
            } else {
                runnable.run();
            }
        }
    }
    private static final class PendingExecutions {