private void addPeekedEvents(List<GatewaySenderEventImpl> batch, int batchSize) {
    if (resetLastPeeked) {

      // Remove all entries from peekedEvents for buckets that are not longer primary
      // This will prevent repeatedly trying to dispatch non-primary events
      Object[] helpArray = peekedEvents.toArray();
      if (helpArray.length > 0) {

        for (int i = helpArray.length - 1; i >= 0; i--) {
          GatewaySenderEventImpl event = (GatewaySenderEventImpl) helpArray[i];
          final int bucketId = event.getBucketId();
          final PartitionedRegion region = (PartitionedRegion) event.getRegion();
          if (!region.getRegionAdvisor().isPrimaryForBucket(bucketId)) {
            peekedEvents.remove(event);
            BucketRegionQueue brq = getBucketRegionQueueByBucketId(getRandomShadowPR(), bucketId);
            if (brq != null) {
              brq.pushKeyIntoQueue(event.getShadowKey());
            }
          }
        }
      }

      if (peekedEventsProcessingInProgress) {
        // Peeked event processing is in progress. This means that the original peekedEvents
        // contained > batch size events due to a reduction in the batch size. Create a batch
        // from the peekedEventsProcessing queue.
        addPreviouslyPeekedEvents(batch, batchSize);
      } else if (peekedEvents.size() <= batchSize) {
        // This is the normal case. The connection was lost while processing a batch.
        // This recreates the batch from the current peekedEvents.
        batch.addAll(peekedEvents);
        resetLastPeeked = false;
      } else {
        // The peekedEvents queue is > batch size. This means that the previous batch size was
        // reduced due to MessageTooLargeException. Create a batch from the peekedEventsProcessing
        // queue.
        // This could also be a normal case in which the batch included extra events to make
        // sure that events for each transaction were sent in the same batch.
        peekedEventsProcessing.addAll(peekedEvents);
        peekedEventsProcessingInProgress = true;
        addPreviouslyPeekedEvents(batch, batchSize);
      }
      if (logger.isDebugEnabled()) {
        StringBuilder buffer = new StringBuilder();
        for (Object ge : batch) {
          buffer.append("event :");
          buffer.append(ge);
        }
        logger.debug("Adding already peeked events to the batch {}", buffer);
      }
    }
  }
Take will choose a random BucketRegionQueue which is primary and will take the head element
from it.
geode-core/src/main/java/org/apache/geode/internal/cache/wan/parallel/ParallelGatewaySenderQueue.java