All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.atomix.copycat.server.RaftServer Maven / Gradle / Ivy

/*
 * Copyright 2015 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.copycat.server;

import io.atomix.catalyst.transport.Address;
import io.atomix.catalyst.util.Managed;
import io.atomix.catalyst.util.concurrent.ThreadContext;

import java.util.Collection;
import java.util.concurrent.CompletableFuture;

/**
 * Provides an interface for managing the lifecycle and state of a Raft server.
 * 

* The lifecycle of the Raft server is managed via the {@link Managed} API methods. To start a server, * call {@link Managed#open()} on the server. Once the server has connected to the cluster and found * a leader, the returned {@link CompletableFuture} will be completed and the server will be operating. *

* Throughout the lifetime of a server, the server transitions between a variety of * {@link io.atomix.copycat.server.RaftServer.State states}. Call {@link #state()} to get the current state * of the server at any given point in time. *

* The {@link #term()} and {@link #leader()} are critical aspects of the Raft consensus algorithm. Initially, * when the server is started, the {@link #term()} will be initialized to {@code 0} and {@link #leader()} will * be {@code null}. By the time the server is fully started, both {@code term} and {@code leader} will be * provided. As the cluster progresses, {@link #term()} will progress monotonically, and for each term, * only a single {@link #leader()} will ever be elected. *

* Raft servers are members of a cluster of servers identified by their {@link Address}. Each server * must be able to locate other members of the cluster. Throughout the lifetime of a cluster, the membership * may change. The {@link #members()} method provides a current view of the cluster from the perspective * of a single server. Note that the members list may not be consistent on all nodes at any given time. * * @author Jordan Halterman */ enum State { /** * Represents the state of an inactive server. *

* All servers start in this state and return to this state when {@link #close() stopped}. */ INACTIVE, /** * Represents the state of a server in the process of catching up its log. *

* Upon successfully joining an existing cluster, the server will transition to the passive state and remain there * until the leader determines that the server has caught up enough to be promoted to a full member. */ PASSIVE, /** * Represents the state of a server participating in normal log replication. *

* The follower state is a standard Raft state in which the server receives replicated log entries from the leader. */ FOLLOWER, /** * Represents the state of a server attempting to become the leader. *

* When a server in the follower state fails to receive communication from a valid leader for some time period, * the follower will transition to the candidate state. During this period, the candidate requests votes from * each of the other servers in the cluster. If the candidate wins the election by receiving votes from a majority * of the cluster, it will transition to the leader state. */ CANDIDATE, /** * Represents the state of a server which is actively coordinating and replicating logs with other servers. *

* Leaders are responsible for handling and replicating writes from clients. Note that more than one leader can * exist at any given time, but Raft guarantees that no two leaders will exist for the same {@link #term()}. */ LEADER } /** * Returns the current Raft term. *

* The term is a monotonically increasing number that essentially acts as a logical time for the cluster. For any * given term, Raft guarantees that only one {@link #leader()} can be elected, but note that a leader may also * not yet exist for the term. * * @return The current Raft term. */ long term(); /** * Returns the current Raft leader. *

* If no leader has been elected, the leader address will be {@code null}. * * @return The current Raft leader or {@code null} if this server does not know of any leader. */ Address leader(); /** * Returns a collection of current cluster members. *

* The current members list includes members in all states, including non-voting states. Additionally, because * the membership set can change over time, the set of members on one server may not exactly reflect the * set of members on another server at any given point in time. * * @return A collection of current Raft cluster members. */ Collection

members(); /** * Returns the Raft server state. *

* The initial state of a Raft server is {@link State#INACTIVE}. Once the server is {@link #open() started} and * until it is explicitly shutdown, the server will be in one of the active states - {@link State#PASSIVE}, * {@link State#FOLLOWER}, {@link State#CANDIDATE}, or {@link State#LEADER}. * * @return The Raft server state. */ State state(); /** * Returns the server execution context. *

* The thread context is the event loop that this server uses to communicate other Raft servers. * Implementations must guarantee that all asynchronous {@link java.util.concurrent.CompletableFuture} callbacks are * executed on a single thread via the returned {@link io.atomix.catalyst.util.concurrent.ThreadContext}. *

* The {@link io.atomix.catalyst.util.concurrent.ThreadContext} can also be used to access the Raft server's internal * {@link io.atomix.catalyst.serializer.Serializer serializer} via {@link ThreadContext#serializer()}. Catalyst serializers * are not thread safe, so to use the context serializer, users should clone it: *

   *   {@code
   *   Serializer serializer = server.threadContext().serializer().clone();
   *   Buffer buffer = serializer.writeObject(myObject).flip();
   *   }
   * 
* * @return The server thread context. */ ThreadContext context(); /** * Starts the Raft server asynchronously. *

* When the server is started, the server will attempt to search for an existing cluster by contacting all of * the members in the provided members list. If no existing cluster is found, the server will immediately transition * to the {@link State#FOLLOWER} state and continue normal Raft protocol operations. If a cluster is found, the server * will attempt to join the cluster. Once the server has joined or started a cluster and a leader has been found, * the returned {@link CompletableFuture} will be completed. * * @return A completable future to be completed once the server has joined the cluster and a leader has been found. */ @Override CompletableFuture open(); /** * Returns a boolean value indicating whether the server is running. *

* Once {@link #open()} is called and the returned {@link CompletableFuture} is completed (meaning this server found * a cluster leader), this method will return {@code true} until {@link #close() closed}. * * @return Indicates whether the server is running. */ @Override boolean isOpen(); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy