docs: private synchronized void keepAliveSessions(long lastKeepAliveTime, long sessionTimeout) {
      // Filter the list of sessions by timeout.
      List<RaftSessionState> needKeepAlive = sessions.values()
          .stream()
          .filter(session -> session.getSessionTimeout() == sessionTimeout)
          .collect(Collectors.toList());
  
      // If no sessions need keep-alives to be sent, skip and reschedule the keep-alive.
      if (needKeepAlive.isEmpty()) {
        return;
      }
  
      // Allocate session IDs, command response sequence numbers, and event index arrays.
      long[] sessionIds = new long[needKeepAlive.size()];
      long[] commandResponses = new long[needKeepAlive.size()];
      long[] eventIndexes = new long[needKeepAlive.size()];
  
      // For each session that needs to be kept alive, populate batch request arrays.
      int i = 0;
      for (RaftSessionState sessionState : needKeepAlive) {
        sessionIds[i] = sessionState.getSessionId().id();
        commandResponses[i] = sessionState.getCommandResponse();
        eventIndexes[i] = sessionState.getEventIndex();
        i++;
      }
  
      log.trace("Keeping {} sessions alive", sessionIds.length);
  
      KeepAliveRequest request = KeepAliveRequest.builder()
          .withSessionIds(sessionIds)
          .withCommandSequences(commandResponses)
          .withEventIndexes(eventIndexes)
          .build();
  
      long keepAliveTime = System.currentTimeMillis();
      connection.keepAlive(request).whenComplete((response, error) -> {
        if (open.get()) {
          long delta = System.currentTimeMillis() - keepAliveTime;
          if (error == null) {
            // If the request was successful, update the address selector and schedule the next keep-alive.
            if (response.status() == RaftResponse.Status.OK) {
              selectorManager.resetAll(response.leader(), response.members());
  
              // Iterate through sessions and close sessions that weren't kept alive by the request (have already been closed).
              Set<Long> keptAliveSessions = Sets.newHashSet(Longs.asList(response.sessionIds()));
              for (RaftSessionState session : needKeepAlive) {
                if (keptAliveSessions.contains(session.getSessionId().id())) {
                  session.setState(PrimitiveState.CONNECTED);
                } else {
                  session.setState(PrimitiveState.EXPIRED);
                }
              }
              scheduleKeepAlive(System.currentTimeMillis(), sessionTimeout, delta);
            }
            // If the timeout has not been passed, attempt to keep the session alive again with no delay.
            // We will continue to retry until the session expiration has passed.
            else if (System.currentTimeMillis() - lastKeepAliveTime < sessionTimeout) {
              selectorManager.resetAll(null, connection.members());
              keepAliveSessions(lastKeepAliveTime, sessionTimeout);
            }
            // If no leader was set, set the session state to unstable and schedule another keep-alive.
            else {
              needKeepAlive.forEach(s -> s.setState(PrimitiveState.SUSPENDED));
              selectorManager.resetAll();
              scheduleKeepAlive(lastKeepAliveTime, sessionTimeout, delta);
            }
          }
          // If the timeout has not been passed, reset the connection and attempt to keep the session alive
          // again with no delay.
          else if (System.currentTimeMillis() - lastKeepAliveTime < sessionTimeout && connection.leader() != null) {
            selectorManager.resetAll(null, connection.members());
            keepAliveSessions(lastKeepAliveTime, sessionTimeout);
          }
          // If no leader was set, set the session state to unstable and schedule another keep-alive.
          else {
            needKeepAlive.forEach(s -> s.setState(PrimitiveState.SUSPENDED));
            selectorManager.resetAll();
            scheduleKeepAlive(lastKeepAliveTime, sessionTimeout, delta);
          }
        }
      });
    }