Similarly to https://github.com/elastic/elasticsearch/pull/97873 but for request handlers: let's stop passing around strings and looking these things up by name on each request when we could just pass around the `Executor` itself.
server/src/main/java/org/elasticsearch/action/support/nodes/TransportNodesAction.java
* @param actionFilters     action filters
     * @param request           node request writer
     * @param nodeRequest       node request reader
     * @param executor          executor to execute node action and final collection
     */
    protected TransportNodesAction(
        String actionName,
        ThreadPool threadPool,
        ClusterService clusterService,
        TransportService transportService,
        ActionFilters actionFilters,
        Writeable.Reader<NodesRequest> request,
        Writeable.Reader<NodeRequest> nodeRequest,
        Executor executor
    ) {
        
        super(actionName, transportService, actionFilters, request, EsExecutors.DIRECT_EXECUTOR_SERVICE);
        assert executor.equals(EsExecutors.DIRECT_EXECUTOR_SERVICE) == false
            : "TransportNodesAction must always fork off the transport thread";
        this.clusterService = Objects.requireNonNull(clusterService);
        this.transportService = Objects.requireNonNull(transportService);
        this.finalExecutor = executor;
        this.transportNodeAction = actionName + "[n]";
        transportService.registerRequestHandler(transportNodeAction, finalExecutor, nodeRequest, new NodeTransportHandler());
    }
    @Override
    protected void doExecute(Task task, NodesRequest request, ActionListener<NodesResponse> listener) {
        if (request.concreteNodes() == null) {
            resolveRequest(request, clusterService.state());
            assert request.concreteNodes() != null;