io.atomix.protocols.raft.storage.log.entry.QueryEntry Java Examples

The following examples show how to use io.atomix.protocols.raft.storage.log.entry.QueryEntry. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: RaftServiceManager.java    From atomix with Apache License 2.0 6 votes vote down vote up
/**
 * Applies a query entry to the state machine.
 * <p>
 * Query entries are applied to the user {@link PrimitiveService} 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.
 */
private CompletableFuture<OperationResult> applyQuery(Indexed<QueryEntry> entry) {
  RaftSession session = raft.getSessions().getSession(entry.entry().session());

  // 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) {
    logger.warn("Unknown session: " + entry.entry().session());
    return Futures.exceptionalFuture(new RaftException.UnknownSession("unknown session " + entry.entry().session()));
  }

  // Execute the query using the state machine associated with the session.
  return session.getService()
      .executeQuery(
          entry.index(),
          entry.entry().sequenceNumber(),
          entry.entry().timestamp(),
          session,
          entry.entry().operation());
}
 
Example #2
Source File: PassiveRole.java    From atomix with Apache License 2.0 5 votes vote down vote up
/**
 * Applies a query to the state machine.
 */
protected CompletableFuture<QueryResponse> applyQuery(Indexed<QueryEntry> entry) {
  // In the case of the leader, the state machine is always up to date, so no queries will be queued and all query
  // indexes will be the last applied index.
  CompletableFuture<QueryResponse> future = new CompletableFuture<>();
  raft.getServiceManager().<OperationResult>apply(entry).whenComplete((result, error) -> {
    completeOperation(result, QueryResponse.builder(), error, future);
  });
  return future;
}
 
Example #3
Source File: LeaderRole.java    From atomix with Apache License 2.0 5 votes vote down vote up
/**
 * Executes a linearizable query.
 * <p>
 * Linearizable queries are first sequenced with commands and then applied to the state machine. Once
 * applied, we verify the node's leadership prior to responding successfully to the query.
 */
private CompletableFuture<QueryResponse> queryLinearizable(Indexed<QueryEntry> entry) {
  return applyQuery(entry)
      .thenComposeAsync(response -> appender.appendEntries()
          .thenApply(index -> response)
          .exceptionally(error -> QueryResponse.builder()
              .withStatus(RaftResponse.Status.ERROR)
              .withError(RaftError.Type.QUERY_FAILURE, error.getMessage())
              .build()), raft.getThreadContext());
}
 
Example #4
Source File: PassiveRole.java    From atomix with Apache License 2.0 4 votes vote down vote up
/**
 * Performs a local query.
 */
protected CompletableFuture<QueryResponse> queryLocal(Indexed<QueryEntry> entry) {
  return applyQuery(entry);
}
 
Example #5
Source File: LeaderRole.java    From atomix with Apache License 2.0 2 votes vote down vote up
/**
 * Executes a bounded linearizable query.
 * <p>
 * Bounded linearizable queries succeed as long as this server remains the leader. This is possible
 * since the leader will step down in the event it fails to contact a majority of the cluster.
 */
private CompletableFuture<QueryResponse> queryBoundedLinearizable(Indexed<QueryEntry> entry) {
  return applyQuery(entry);
}