@Override
    public void messageReceived(Request request, final TransportChannel channel) throws Exception {
      // we just send back a response, no need to fork a listener
      request.listenerThreaded(false);
      // we don't spawn, so if we get a request with no threading, change it to single threaded
      if (request.operationThreading() == BroadcastOperationThreading.NO_THREADS) {
        request.operationThreading(BroadcastOperationThreading.SINGLE_THREAD);
      }
      execute(
          request,
          new ActionListener<Response>() {
            @Override
            public void onResponse(Response response) {
              try {
                channel.sendResponse(response);
              } catch (Throwable e) {
                onFailure(e);
              }
            }

            @Override
            public void onFailure(Throwable e) {
              try {
                channel.sendResponse(e);
              } catch (Exception e1) {
                logger.warn("Failed to send response", e1);
              }
            }
          });
    }
 public void start() {
   if (shardsIts.size() == 0) {
     // no shards
     try {
       listener.onResponse(newResponse(request, new AtomicReferenceArray(0), clusterState));
     } catch (Throwable e) {
       listener.onFailure(e);
     }
   }
   request.beforeStart();
   // count the local operations, and perform the non local ones
   int localOperations = 0;
   int shardIndex = -1;
   for (final ShardIterator shardIt : shardsIts) {
     shardIndex++;
     final ShardRouting shard = shardIt.firstOrNull();
     if (shard != null) {
       if (shard.currentNodeId().equals(nodes.localNodeId())) {
         localOperations++;
       } else {
         // do the remote operation here, the localAsync flag is not relevant
         performOperation(shardIt, shardIndex, true);
       }
     } else {
       // really, no shards active in this group
       onOperation(
           null, shardIt, shardIndex, new NoShardAvailableActionException(shardIt.shardId()));
     }
   }
   // we have local operations, perform them now
   if (localOperations > 0) {
     if (request.operationThreading() == BroadcastOperationThreading.SINGLE_THREAD) {
       request.beforeLocalFork();
       threadPool
           .executor(executor)
           .execute(
               new Runnable() {
                 @Override
                 public void run() {
                   int shardIndex = -1;
                   for (final ShardIterator shardIt : shardsIts) {
                     shardIndex++;
                     final ShardRouting shard = shardIt.firstOrNull();
                     if (shard != null) {
                       if (shard.currentNodeId().equals(nodes.localNodeId())) {
                         performOperation(shardIt, shardIndex, false);
                       }
                     }
                   }
                 }
               });
     } else {
       boolean localAsync =
           request.operationThreading() == BroadcastOperationThreading.THREAD_PER_SHARD;
       if (localAsync) {
         request.beforeLocalFork();
       }
       shardIndex = -1;
       for (final ShardIterator shardIt : shardsIts) {
         shardIndex++;
         final ShardRouting shard = shardIt.firstOrNull();
         if (shard != null) {
           if (shard.currentNodeId().equals(nodes.localNodeId())) {
             performOperation(shardIt, shardIndex, localAsync);
           }
         }
       }
     }
   }
 }