void drain(final ClientRegistrationEventQueue clientRegistrationEventQueue,
      final CacheClientNotifier cacheClientNotifier) {
    try {
      ClientProxyMembershipID clientProxyMembershipID =
          clientRegistrationEventQueue.getClientProxyMembershipID();

      if (logger.isDebugEnabled()) {
        logger.debug("Draining events from registration queue for client proxy "
            + clientProxyMembershipID
            + " without synchronization");
      }

      CacheClientProxy cacheClientProxy =
          cacheClientNotifier.getClientProxy(clientProxyMembershipID);

      drainEventsReceivedWhileRegisteringClient(cacheClientProxy, clientRegistrationEventQueue,
          cacheClientNotifier);

      // Prevents additional events from being added to the queue while we process and remove it
      clientRegistrationEventQueue.lockForDraining();

      if (logger.isDebugEnabled()) {
        logger.debug("Draining remaining events from registration queue for client proxy "
            + clientProxyMembershipID
            + " with synchronization");
      }

      drainEventsReceivedWhileRegisteringClient(cacheClientProxy, clientRegistrationEventQueue,
          cacheClientNotifier);
    } finally {
      // The queue must be removed before attempting to release the drain lock
      // so that no additional events can be added from add threads.
      registeringProxyEventQueues.remove(clientRegistrationEventQueue);

      if (clientRegistrationEventQueue.isLockForDrainingHeld()) {
        clientRegistrationEventQueue.unlockForDraining();
      }
    }
  }
This class is responsible for queueing events for clients while they are registering. Once the
client is completely registered (filter info retrieved and GII complete), we will drain the
client's queued events and deliver them to the cache client proxy if necessary.
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientRegistrationEventQueueManager.java