code: AcquireResult drain(SemaphoreEndpoint endpoint, UUID invocationUid) {
          SessionSemaphoreState state = sessionStates.get(endpoint.sessionId());
          if (state != null) {
              Integer permits = state.getInvocationResponse(endpoint.threadId(), invocationUid);
              if (permits != null) {
                  return new AcquireResult(permits, Collections.<AcquireInvocationKey>emptyList());
              }
          }
  
          Collection<AcquireInvocationKey> cancelled = cancelWaitKeys(endpoint, invocationUid);
  
          int drained = available;
          if (drained > 0) {
              assignPermitsToInvocation(endpoint, invocationUid, drained);
          }
          available = 0;
  
          return new AcquireResult(drained, cancelled);
      }
docs: Assigns all available permits to the <sessionId, threadId> endpoint.
  Permits are not assigned if the drain request is a retry of a successful
  drain request of a session-aware proxy. Permits are assigned again if
  the drain request is a retry of a successful drain request of
  a sessionless proxy. Returns cancelled wait keys of the same endpoint
  if there are any.