code: private void releaseSession(PooledSession session) {
      Preconditions.checkNotNull(session);
      synchronized (lock) {
        if (closureFuture != null) {
          return;
        }
        if (readWaiters.size() == 0 && numSessionsBeingPrepared >= readWriteWaiters.size()) {
          // No pending waiters
          if (shouldPrepareSession()) {
            prepareSession(session);
          } else {
            readSessions.add(session);
          }
        } else if (shouldUnblockReader()) {
          readWaiters.poll().put(session);
        } else {
          prepareSession(session);
        }
      }
    }
docs: Releases a session back to the pool. This might cause one of the waiters to be unblocked.
  
  <p>Implementation note:
  
  <ol>
  <li>If there are no pending waiters, either add to the read sessions queue or start preparing
  for write depending on what fraction of sessions are already prepared for writes.
  <li>Otherwise either unblock a waiting reader or start preparing for a write. Exact strategy
  on which option we chose, in case there are both waiting readers and writers, is
  implemented in {@link #shouldUnblockReader}
  </ol>