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/broadcast/unpromotable/TransportBroadcastUnpromotableAction.java
}
                unpromotableShards.forEach(shardRouting -> {
                    final DiscoveryNode node = clusterState.nodes().get(shardRouting.currentNodeId());
                    final ActionListener<Response> shardRequestListener = listeners.acquire(response -> {
                        synchronized (responses) {
                            responses.add(response);
                        }
                    });
                    transportService.sendRequest(
                        node,
                        transportUnpromotableAction,
                        request,
                        TransportRequestOptions.EMPTY,
                        new ActionListenerResponseHandler<>(
                            request.failShardOnError()
                                ? shardRequestListener.delegateResponse((l, e) -> failShard(shardRouting, clusterState, l, e))
                                : shardRequestListener,
                            this::readResponse,
                            executor
                        )
                    );
                });
                return null;
            });
        }
    }
    protected abstract Response combineUnpromotableShardResponses(List<Response> responses);
    protected abstract Response readResponse(StreamInput in) throws IOException;
    protected abstract Response emptyResponse();
    private void failShard(ShardRouting shardRouting, ClusterState clusterState, ActionListener<Response> l, Exception e) {