/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package io.atomix.resource;
import io.atomix.copycat.Query;
/**
* Constants for controlling read consistency constraints on a per-request basis.
* <p>
* Read consistency levels dictate how queries should be evaluated in the Atomix cluster. Resources generally have
* significantly greater flexibility in controlling the consistency level of reads because Raft allows reads from
* leaders or followers. Consistency levels can be applied on a per-command basis or to all operations for a given
* resource.
*
* @author <a href="http://github.com/kuujo>Jordan Halterman</a>
*/
public enum ReadConsistency {
/**
* Guarantees atomicity (linearizability) for read operations.
* <p>
* The atomic consistency level guarantees linearizability by contacting a majority of the cluster on every read.
* When a {@link Query} is submitted to the cluster with linearizable consistency, it must be
* forwarded to the current cluster leader. Once received by the leader, the leader will contact a majority of the
* cluster before applying the query to its state machine and returning the result. Note that if the leader is already
* in the process of contacting a majority of the cluster, it will queue the {@link Query} to
* be processed on the next round trip. This allows the leader to batch expensive quorum based reads for efficiency.
*/
ATOMIC(Query.ConsistencyLevel.LINEARIZABLE),
/**
* Provides linearizability under a leader lease.
* <p>
* Atomic lease consistency is a special implementation of linearizable reads that relies on the semantics of Raft's
* election timers to determine whether it is safe to immediately apply a query to the Raft state machine. When a
* linearizable {@link Query} is submitted to the Raft cluster with linearizable consistency,
* it must be forwarded to the current cluster leader. For lease-based linearizability, the leader will determine whether
* it's safe to apply the query to its state machine based on the last time it successfully contacted a majority of the
* cluster. If the leader contacted a majority of the cluster within the last election timeout, it assumes that no other
* member could have since become the leader and immediately applies the query to its state machine. Alternatively, if it
* hasn't contacted a majority of the cluster within an election timeout, the leader will handle the query as if it were
* submitted with {@link #ATOMIC} consistency.
*/
ATOMIC_LEASE(Query.ConsistencyLevel.LINEARIZABLE_LEASE),
/**
* Guarantees sequential consistency for read operations.
* <p>
* Sequential read consistency requires that clients always see state progress in monotonically increasing order. Note that
* this constraint allows reads from followers. When a sequential {@link Query} is submitted to the cluster, the first
* server that receives the query will handle it. However, in order to ensure that state does not go back in time, the
* client must submit its last known index with the query as well. If the server that receives the query has not advanced
* past the provided client index, it will queue the query and await more entries from the leader.
*/
SEQUENTIAL(Query.ConsistencyLevel.SEQUENTIAL),
/**
* Reads state from a local cache if possible, otherwise guarantees sequential consistency.
* <p>
* This is a special consistency level specifically for use in resources that support local caching. When state is read
* using {@code LOCAL} read consistency, cached resources will attempt to service the read from the local cache and
* fall back to {@link #SEQUENTIAL} communication with the cluster. State changes in the local cache must be similarly
* guaranteed to occur in sequential order.
*/
LOCAL(Query.ConsistencyLevel.SEQUENTIAL);
private final Query.ConsistencyLevel level;
ReadConsistency(Query.ConsistencyLevel level) {
this.level = level;
}
public Query.ConsistencyLevel level() {
return level;
}
}