Interface JGroupsRaft<T>

Type Parameters:
T - the type of the state machine.

@ThreadSafe public interface JGroupsRaft<T>
Entry point for the JGroups Raft API.

The JGroupsRaft interface serves as the main entry point for interacting with the JGroups Raft. It provides methods to build, run, and manage replicated state machines based on the Raft consensus algorithm. This interface includes methods to start and stop the instance, submit commands to the replicated state machine, perform administrative tasks, and access the current state of the underlying Raft1 algorithm. Additionally, the JGroupsRaft instance is thread-safe.

Instantiation

To create a new instance of JGroupsRaft, use the builder(Object, Class) method. This method returns a JGroupsRaft.Builder instance, which can be used to configure and build the instance. The builder requires a state machine and configuration settings to construct a JChannel instance.

The builder also allows registering custom serialization context initializers and marshaller to serialize data. Additionally, it provides access to a RaftProtocolBuilder to configure the underlying RAFT protocol.

Lifecycle

The lifecycle of the JGroupsRaft instance is managed through the start() and stop() methods. The start() method initializes the instance, connects to the underlying JGroups channel, and starts the Raft algorithm. Conversely, the stop() method halts the Raft algorithm, disconnects from the JGroups channel, and cleans up any resources utilized by the instance. It's important to note that a single instance can only be started once and cannot be restarted after it has been stopped.

Usage Steps

Start

After creating an instance using the JGroupsRaft.Builder, before submitting any operations, the instance must be started by invoking the start() method. This will initialize internal components and connect to the cluster as defined in the configuration. Once started, users can submit operations to the state machine for replication and processing.

The initialization phase includes the generation of a schema based on the state machine's methods. This schema is used to validate compatibility between versions of the application. The schema is loaded from the local node log and verified against the current version provided to the instance. If the schema is not compatible, an exception will be thrown.

The start method is also responsible for connecting to the underlying JGroups channel. This step will create the cluster and initialize the RAFT protocol. The state machine is restored from the log during this phase.

Stop

When the instance is no longer needed, it should be stopped by calling the stop() method. This will disconnect from the cluster and clean up all resources. The schema generated by the state machine will be flushed to the local log, making the instance unusable afterward. Any subsequent attempts to start the instance or submit operations will result in failure.

If a JChannel is provided during configuration, and it is already connected, the instance will not manage its lifecycle. Invoking start() or stop() methods will have no effect on the channel. However, these methods are still required to initialize internal components properly. In such cases, it is the application's responsibility to handle the channel's lifecycle, including stopping it when necessary.

Command Submission

After initialization, we can submit operations with the write(Function) and read(Function) methods and its variants. These method provides a functional interface to execute the command using the state machine as argument. The write(Function) method is used for commands that modify the state machine, while the read(Function) method is used for commands that only read the state machine's state.

Administration

The administration() method provides access to the administrative interface. This interface is aimed at operators to perform administrative tasks to manage the cluster. See JGroupsRaftAdministration for more information.

State

The state() method provides access to the current state of the RAFT protocol. This information is useful for monitoring the state of the Raft algorithm1 and understanding the current status of the cluster. See JGroupsRaftState for more information.

Since:
2.0
Author:
José Bolina
See Also:
  • Method Details

    • builder

      static <T> JGroupsRaft.JGroupsBuilderStep<JGroupsRaft<T>, JGroupsRaft.Builder<T>> builder(T stateMachine, Class<T> api)
      Creates a new builder to configure the JGroupsRaft instance.
      Type Parameters:
      T - the type of the state machine
      Parameters:
      stateMachine - the concrete local implementation of the state machine. The state machine should not be null.
      api - the class defining the state machine API. The class should not be null.
      Returns:
      a new builder to configure the JGroupsRaft instance.
      Throws:
      NullPointerException - if any of the arguments is null.
    • start

      void start()
      Starts the instance.

      This method initializes the instance, connects to the underlying JGroups channel, and starts the Raft algorithm. This method must be invoked before submitting any commands. An instance can not be utilized after it is stop().

      Throws:
      IllegalStateException - in case of misconfiguration of the JGroups channel or trying to restart the instance.
    • stop

      void stop()
      Stops the instance.

      The node will disconnect from the cluster and stop the Raft algorithm. A schema generated from the state machine is flushed to the log for backwards compatibility validation. After the instance is stopped, it can not be utilized or restarted.

    • role

      The current role of the node in the Raft algorithm.
      Returns:
      the current role of the node in the Raft algorithm.
    • write

      default <O> O write(Function<T,O> function)
      Submits a write command to the state machine.

      The function accepts a state machine as argument. The function should utilize the state machine to invoke the methods annotated with StateMachineWrite. When the method is invoked, it will replicate the command across the cluster and wait for the command to be committed. Once the command is committed, the function will return.

      Only the methods are invoked in Raft. The lambda is executed locally and is not atomic.
      Type Parameters:
      O - the type of the result.
      Parameters:
      function - the function to execute using the state machine as argument.
      Returns:
      the result of the function.
    • write

      <O> O write(Function<T,O> function, JGroupsRaftWriteCommandOptions options)
      Submits a write command to the state machine.

      This method is similar to write(Function), but it accepts options to change the command behavior during execution.

      Only the methods are invoked in Raft. The lambda is executed locally and is not atomic.
      Type Parameters:
      O - the type of the result.
      Parameters:
      function - the function to execute using the state machine as argument.
      options - options to change the command behavior during execution.
      Returns:
      the result of the function.
      See Also:
    • read

      default <O> O read(Function<T,O> function)
      Submits a read command to the state machine.

      The function accepts a state machine as argument. The function should utilize the state machine to invoke the methods annotated with StateMachineRead. When the method is invoked, it will submit the command through the Raft algorithm. Depending on the configuration, the command may be served locally or by the leader. Once the command is executed, the function will return.

      Only the methods are invoked in Raft. The lambda is executed locally and is not atomic.
      Type Parameters:
      O - the type of the result.
      Parameters:
      function - the function to execute using the state machine as argument.
      Returns:
      the result of the function.
    • read

      <O> O read(Function<T,O> function, JGroupsRaftReadCommandOptions options)
      Submits a read command to the state machine.

      This method is similar to read(Function), but it accepts options to change the command behavior during execution.

      Only the methods are invoked in Raft. The lambda is executed locally and is not atomic.
      Type Parameters:
      O - the type of the result.
      Parameters:
      function - the function to execute using the state machine as argument.
      options - options to change the command behavior during execution.
      Returns:
      the result of the function.
    • administration

      JGroupsRaftAdministration administration()
      Administrative interface to manage the cluster.

      This API provides methods for administrative tasks, aimed for operator or scripting.

      Returns:
      an API to manage the cluster.
    • state

      Internal state of the Raft algorithm.

      This API provides a read-only view of the internals of the Raft algorithm. This is information is useful to analyze how the cluster is behaving.

      Returns:
      Raft's internal state.
    • metrics

      Metrics related to the Raft algorithm and command execution.

      This API provides access to metrics related to the Raft algorithm and command execution. The metrics can be utilized to monitor the cluster's performance and behavior.

      Returns:
      metrics related to the Raft algorithm and command execution.
    • healthCheck

      JGroupsRaftHealthCheck healthCheck()
      Health check utility to check the node health.

      Health check is local, no calls are run remotely. The caller can invoke the methods periodically to verify the local node's health. Collecting the health of all nodes in the cluster is the responsibility of the caller.

      Returns:
      health check utility
      See Also:
    • listenRoleChanges

      void listenRoleChanges(BiConsumer<JGroupsRaftRole, JGroupsRaftRole> consumer)
      Registers a listener to be notified when the role of the node changes.

      The consumer is invoked when the role of the node changes. The consumer is synchronously and should not block.

      Parameters:
      consumer - the consumer to be notified when the role of the node changes.
    • removeRoleChangeListener

      void removeRoleChangeListener(BiConsumer<JGroupsRaftRole, JGroupsRaftRole> consumer)
      Removes a previously registered listener.
      Parameters:
      consumer - the consumer to be removed.