@Override
  public void stopProcessing() {
    if (!isAlive()) {
      return;
    }

    setIsStopped(true);

    List<SenderStopperCallable> stopperCallables = new ArrayList<>();
    for (ParallelGatewaySenderEventProcessor parallelProcessor : processors) {
      stopperCallables.add(new SenderStopperCallable(parallelProcessor));
    }

    ExecutorService stopperService = LoggingExecutors.newFixedThreadPool(
        processors.length, "ConcurrentParallelGatewaySenderEventProcessor Stopper Thread",
        true);
    try {
      List<Future<Boolean>> futures = stopperService.invokeAll(stopperCallables);
      for (Future<Boolean> f : futures) {
        try {
          Boolean b = f.get();
          if (logger.isDebugEnabled()) {
            logger.debug(
                "ConcurrentParallelGatewaySenderEventProcessor: {} stopped dispatching: {}",
                (b ? "Successfully" : "Unsuccessfully"), this);
          }
        } catch (ExecutionException e) {
          // we don't expect any exception but if caught then eat it and log warning
          logger.warn("GatewaySender {} caught exception while stopping:", sender,
              e);
        }
      }
    } catch (InterruptedException e) {
      throw new InternalGemFireException(e);
    }

    stopperService.shutdown();
    closeProcessor();
    if (logger.isDebugEnabled()) {
      logger.debug("ConcurrentParallelGatewaySenderEventProcessor: Stopped dispatching: {}", this);
    }
  }
Parallel processor which constitutes of multiple {@link ParallelGatewaySenderEventProcessor}.
Each of the {@link ParallelGatewaySenderEventProcessor} is responsible of dispatching events from
a set of shadowPR or buckets. Once the buckets/shadowPRs are assigned to a processor it should
not change to avoid any event ordering issue.

The {@link ParallelGatewaySenderQueue} should be shared among all the
{@link ParallelGatewaySenderEventProcessor}s.
geode-core/src/main/java/org/apache/geode/internal/cache/wan/parallel/ConcurrentParallelGatewaySenderEventProcessor.java