private CompletableFuture<Result> apply(QueryEntry entry) {
    ServerSessionContext session = executor.context().sessions().getSession(entry.getSession());

    // If the session is null then that indicates that the session already timed out or it never existed.
    // Return with an UnknownSessionException.
    if (session == null) {
      return Futures.exceptionalFuture(new UnknownSessionException("unknown session " + entry.getSession()));
    }
    // If the session is not in an active state, return an UnknownSessionException. Sessions are retained in the
    // session registry until all prior commands have been released by the state machine, but new operations can
    // only be applied for sessions in an active state.
    else if (!session.state().active()) {
      return Futures.exceptionalFuture(new UnknownSessionException("inactive session: " + entry.getSession()));
    } else {
      CompletableFuture<Result> future = new CompletableFuture<>();
      ThreadContext context = ThreadContext.currentContextOrThrow();
      ServerCommit commit = commits.acquire(entry.setIndex(lastApplied), session, executor.timestamp());
      executor.executor().execute(() -> executeQuery(commit, session, future, context));
      return future;
    }
  }
private CompletableFuture < Result > apply ( QueryEntry entry ) { ServerSessionContext session = executor . context ( ) . sessions ( ) . getSession ( entry . getSession ( ) ) ; if ( session == null ) { return Futures . exceptionalFuture ( new UnknownSessionException ( "unknown session " + entry . getSession ( ) ) ) ; } else if ( ! session . state ( ) . active ( ) ) { return Futures . exceptionalFuture ( new UnknownSessionException ( "inactive session: " + entry . getSession ( ) ) ) ; } else { CompletableFuture < Result > future = new CompletableFuture < > ( ) ; ThreadContext context = ThreadContext . currentContextOrThrow ( ) ; ServerCommit commit = commits . acquire ( entry . setIndex ( lastApplied ) , session , executor . timestamp ( ) ) ; executor . executor ( ) . execute ( ( ) -> executeQuery ( commit , session , future , context ) ) ; return future ; } }
Applies a query entry to the state machine.
<p>
Query entries are applied to the user {@link StateMachine} for read-only operations.
Because queries are read-only, they may only be applied on a single server in the cluster,
and query entries do not go through the Raft log. Thus, it is critical that measures be taken
to ensure clients see a consistent view of the cluster event when switching servers. To do so,
clients provide a sequence and version number for each query. The sequence number is the order
in which the query was sent by the client. Sequence numbers are shared across both commands and
queries. The version number indicates the last index for which the client saw a command or query
response. In the event that the lastApplied index of this state machine does not meet the provided
version number, we wait for the state machine to catch up before applying the query. This ensures
clients see state progress monotonically even when switching servers.
<p>
Because queries may only be applied on a single server in the cluster they cannot result in the
publishing of session events. Events require commands to be written to the Raft log to ensure
fault-tolerance and consistency across the cluster.