`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
}
                        }
                    });
                } catch (final Exception e) {
                    try {
                        /*
                         * It is possible to run into connection exceptions here because we are getting the connection early and might
                         * run into nodes that are not connected. In this case, on shard failure will move us to the next shard copy.
                         */
                        fork(() -> onShardFailure(shardIndex, shard, shardIt, e));
                    } finally {
                        executeNext(pendingExecutions, thread);
                    }
                }
            };
            if (throttleConcurrentRequests) {
                pendingExecutions.tryRun(r);
            } else {
                r.run();
            }
        }
    }
    /**
     * Sends the request to the actual shard.
     * @param shardIt the shards iterator
     * @param shard the shard routing to send the request for
     * @param listener the listener to notify on response
     */
    protected abstract void executePhaseOnShard(
        SearchShardIterator shardIt,