private List<GatewaySenderEventImpl> addPDXEvent() throws IOException {
    List<GatewaySenderEventImpl> pdxEventsToBeDispatched = new ArrayList<>();

    // getPDXRegion
    InternalCache cache = sender.getCache();
    Region<Object, Object> pdxRegion = cache.getRegion(PeerTypeRegistration.REGION_NAME);

    if (rebuildPdxList) {
      pdxEventsMap.clear();
      pdxSenderEventsList.clear();
      rebuildPdxList = false;
    }

    // find out the list of the PDXEvents which needs to be send across remote
    // site
    // these events will be added to list pdxSenderEventsList. I am expecting
    // that PDX events will be only added to PDX region. no deletion happens on
    // PDX region
    if (pdxRegion != null && pdxRegion.size() != pdxEventsMap.size()) {
      for (Map.Entry<Object, Object> typeEntry : pdxRegion.entrySet()) {
        if (!pdxEventsMap.containsKey(typeEntry.getKey())) {
          // event should never be off-heap so it does not need to be released
          EntryEventImpl event = EntryEventImpl.create((LocalRegion) pdxRegion, Operation.UPDATE,
              typeEntry.getKey(), typeEntry.getValue(), null, false, cache.getMyId());
          event.disallowOffHeapValues();
          event.setEventId(new EventID(cache.getInternalDistributedSystem()));
          List<Integer> allRemoteDSIds = new ArrayList<>();
          for (GatewaySender sender : cache.getGatewaySenders()) {
            allRemoteDSIds.add(sender.getRemoteDSId());
          }
          GatewaySenderEventCallbackArgument geCallbackArg = new GatewaySenderEventCallbackArgument(
              event.getRawCallbackArgument(), sender.getMyDSId(), allRemoteDSIds);
          event.setCallbackArgument(geCallbackArg);
          // OFFHEAP: event for pdx type meta data so it should never be off-heap
          GatewaySenderEventImpl pdxSenderEvent =
              new GatewaySenderEventImpl(EnumListenerEvent.AFTER_UPDATE, event, null);

          pdxEventsMap.put(typeEntry.getKey(), pdxSenderEvent);
          pdxSenderEventsList.add(pdxSenderEvent);
        }
      }
    }

    Iterator<GatewaySenderEventImpl> iterator = pdxSenderEventsList.iterator();
    while (iterator.hasNext()) {
      GatewaySenderEventImpl pdxEvent = iterator.next();
      if (pdxEvent.isAcked) {
        // Since this is acked, it means it has reached to remote site.Dont add
        // to pdxEventsToBeDispatched
        iterator.remove();
        continue;
      }
      if (pdxEvent.isDispatched) {
        // Dispacther does not mean that event has reched remote site. We may
        // need to send it agian if there is porblem while receiveing ack
        // containing this event.Dont add to pdxEventsToBeDispatched
        continue;
      }
      pdxEventsToBeDispatched.add(pdxEvent);
    }

    if (!pdxEventsToBeDispatched.isEmpty() && logger.isDebugEnabled()) {
      logger.debug("List of PDX Event to be dispatched : {}", pdxEventsToBeDispatched);
    }

    // add all these pdx events before filtered events
    return pdxEventsToBeDispatched;
  }
After a successful batch execution remove from failure map if present (i.e. if the event had
failed on a previous try).
geode-core/src/main/java/org/apache/geode/internal/cache/wan/AbstractGatewaySenderEventProcessor.java