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
shardStateAction.remoteShardFailed(
            shardRouting.shardId(),
            shardRouting.allocationId().getId(),
            clusterState.metadata().index(shardRouting.getIndexName()).primaryTerm(shardRouting.shardId().getId()),
            true,
            "mark unpromotable copy as stale after refresh failure",
            e,
            new ActionListener<>() {
                @Override
                public void onResponse(Void unused) {
                    logger.debug("Marked shard {} as failed", shardRouting.shardId());
                    l.onResponse(emptyResponse());
                }
                @Override
                public void onFailure(Exception sfe) {
                    logger.error(Strings.format("Unable to mark shard [%s] as failed", shardRouting.shardId()), sfe);
                    l.onFailure(e);
                }
            }
        );
    }
    class UnpromotableTransportHandler implements TransportRequestHandler<Request> {
        @Override
        public void messageReceived(Request request, TransportChannel channel, Task task) throws Exception {
            final ActionListener<Response> listener = new ChannelActionListener<>(channel);
            ActionListener.run(listener, (l) -> unpromotableShardOperation(task, request, l));
        }
    }
}