@Override
  public void destroy(boolean initiator) {
    try {
      getLifeCycleLock().writeLock().lock();
      // first, check if this sender is attached to any region. If so, throw
      // GatewaySenderException
      Set<InternalRegion> regions = cache.getApplicationRegions();
      for (final InternalRegion internalRegion : regions) {
        LocalRegion region = (LocalRegion) internalRegion;

        if (region.getAttributes().getGatewaySenderIds().contains(id)) {
          throw new GatewaySenderException(
              String.format(
                  "The GatewaySender %s could not be destroyed as it is still used by region(s).",
                  this));
        }
      }
      // close the GatewaySenderAdvisor
      GatewaySenderAdvisor advisor = getSenderAdvisor();
      if (advisor != null) {
        if (logger.isDebugEnabled()) {
          logger.debug("Stopping the GatewaySender advisor");
        }
        advisor.close();
      }

      // remove the sender from the cache
      cache.removeGatewaySender(this);

      // destroy the region underneath the sender's queue
      if (initiator) {
        Set<RegionQueue> regionQueues = getQueues();
        if (regionQueues != null) {
          for (RegionQueue regionQueue : regionQueues) {
            try {
              if (regionQueue instanceof ConcurrentParallelGatewaySenderQueue) {
                Set<PartitionedRegion> queueRegions =
                    ((ConcurrentParallelGatewaySenderQueue) regionQueue).getRegions();
                for (PartitionedRegion queueRegion : queueRegions) {
                  queueRegion.destroyRegion();
                }
              } else {// For SerialGatewaySenderQueue, do local destroy
                regionQueue.getRegion().localDestroyRegion();
              }
            }
            // Can occur in case of ParallelGatewaySenderQueue, when the region is
            // being destroyed
            // by several nodes simultaneously
            catch (RegionDestroyedException e) {
              // the region might have already been destroyed by other node. Just
              // log
              // the exception.
              logger.info(
                  "Region {} that underlies the GatewaySender {} is already destroyed.",
                  e.getRegionFullPath(), this);
            }
          }
        } // END if (regionQueues != null)
      }
    } finally {
      getLifeCycleLock().writeLock().unlock();
    }
  }
Destroys the GatewaySender. Before destroying the sender, caller needs to to ensure that the
sender is stopped so that all the resources (threads, connection pool etc.) will be released
properly. Stopping the sender is not handled in the destroy. Destroy is carried out in
following steps: 1. Take the lifeCycleLock. 2. If the sender is attached to any application
region, throw an exception. 3. Close the GatewaySenderAdvisor. 4. Remove the sender from the
cache. 5. Destroy the region underlying the GatewaySender.

In case of ParallelGatewaySender, the destroy operation does distributed destroy of the QPR. In
case of SerialGatewaySender, the queue region is destroyed locally.
geode-core/src/main/java/org/apache/geode/internal/cache/wan/AbstractGatewaySender.java