code: private void expireSession(long index, long timestamp, ServerSessionContext session, CompletableFuture<Void> future, ThreadContext context) {
      if (!log.isOpen()) {
        context.executor().execute(() -> future.completeExceptionally(new IllegalStateException("log closed")));
        return;
      }
  
      // If the session is already in an inactive state, complete the future exceptionally.
      if (!session.state().active()) {
        context.executor().execute(() -> future.completeExceptionally(new UnknownSessionException("inactive session: " + session.id())));
        return;
      }
  
      // Trigger scheduled callbacks in the state machine.
      executor.tick(index, timestamp);
  
      // Update the state machine context with the unregister entry's index. This ensures that events published
      // within the expire or close methods will be properly associated with the unregister entry's index.
      // All events published during expiration or closing of a session are linearizable to ensure that clients
      // receive related events before the expiration is completed.
      executor.init(index, Instant.ofEpochMilli(timestamp), ServerStateMachineContext.Type.COMMAND);
  
      // Expire the session and call state machine callbacks.
      session.expire(index);
      for (SessionListener listener : executor.context().sessions().listeners) {
        listener.expire(session);
        listener.close(session);
      }
  
      // Calculate the last completed index.
      long lastCompleted = calculateLastCompleted(index);
  
      // Once expiration callbacks have been completed, ensure that events published during the callbacks
      // are published in batch. The state machine context will generate an event future for all published events
      // to all sessions. If the event future is non-null, that indicates events are pending which were published
      // during the call to expire(). Wait for the events to be received by the client before completing the future.
      executor.commit();
      context.executor().execute(() -> {
        setLastCompleted(lastCompleted);
        future.complete(null);
      });
    }
docs: Expires the given session.