Three interrelated issues here:

- [ ] `TransportBroadcastByNodeAction` derivatives are typically executed via `NodeClient` which bypasses the `TransportService` and therefore does not respect (or even know about) the `executor` parameter which would fork. This means that the coordination work, including grouping all the shards by node, happens on the calling thread. When executed from the REST layer, that's a transport worker. This is #97916, but until that's fixed we need a workaround.

- [ ] The node-level responses are deserialised and processed on the receiving transport worker too.

- [ ] Several of these actions use `SAME` for their executor, bypassing the forking that _does_ exist today.

Relates #77466 
server/src/test/java/org/elasticsearch/action/support/broadcast/node/TransportBroadcastByNodeActionTests.java
action.new NodeRequest(
                new Request(), IntStream.range(0, 3)
                    .mapToObj(shardId -> TestShardRouting.newShardRouting(TEST_INDEX, shardId, "node-id", true, ShardRoutingState.STARTED))
                    .toList(), "node-id"
            ),
            new TestTransportChannel(nodeResponseFuture),
            new CancellableTask(randomLong(), "transport", "action", "", null, emptyMap())
        );
        assertTrue(nodeResponseFuture.isDone());
        assertEquals(
            "task cancelled [simulated]",
            expectThrows(
                java.util.concurrent.ExecutionException.class,
                org.elasticsearch.tasks.TaskCancelledException.class,
                nodeResponseFuture::get
            ).getMessage()
        );
    }
    public void testShardResultsReleasedOnCancellation() throws Exception {
        final var listeners = new ArrayList<ActionListener<ShardResult>>();
        action = new TestTransportBroadcastByNodeAction("indices:admin/shard_level_gc_test") {
            @Override
            protected void shardOperation(Request request, ShardRouting shardRouting, Task task, ActionListener<ShardResult> listener) {
                listeners.add(listener);
            }
        };
        final PlainActionFuture<TransportResponse> nodeResponseFuture = new PlainActionFuture<>();
        final CancellableTask task = new CancellableTask(randomLong(), "transport", "action", "", null, emptyMap());
        action.new BroadcastByNodeTransportRequestHandler().messageReceived(
            action.new NodeRequest(