Connects this RaftController to the Raft cluster. Users of this
RaftController need to wait til the returned promise is resolved before
they can propose inputs with propose(...), observe the replicated state
with getState() and observeState(), and monitor the cluster
configuration with getClusterConfiguration() and
observeClusterConfiguration().
If this function is called after a crash and this RaftController was
connected to the Raft cluster before the crash, persisted data will be
used to restore this controller and reconnect to the Raft cluster.
A promise that resolves once this RaftController has connected
to the Raft cluster.
The RaftController with
shouldCreateCluster set to true will
create a new Raft cluster on initial startup. Trying to connect a
RaftController with this option set to false will only resolve after
a Raft cluster has been created and a majority of the existing cluster
has agreed on letting this RaftController join.
An InvalidControllerOptionsError if the
RaftControllerOptions provided when bootstrapping this
controller are invalid or missing.
An OperationNotSupportedInCurrentConnectionStateError
if this controller is currently in the process of disconnecting or
stopping.
Disconnects this RaftController from the Raft cluster therefore
removing it from the cluster configuration. Users of this
RaftController need to wait til the returned promise is resolved before
they can shutdown the corresponding Coaty container. Deletes all
persisted state of this controller. The shared state of a Raft cluster is
lost after all RaftControllers of that cluster have disconnected.
A promise that resolves once this RaftController has
disconnected.
An OperationNotSupportedInCurrentConnectionStateError
if this controller is currently in the process of connecting or stopping.
Returns a promise resolving to the cluster configuration. The cluster
configuration contains the ids of all RaftControllers in the cluster.
A promise resolving to the cluster configuration. The cluster
configuration contains the ids of all RaftControllers in the cluster.
The returned configuration is guaranteed to be up to date or
newer respective to the point in time when this function was called. In
other words calling getClusterConfiguration() at time t will return the
cluster configuration from some point in time inside [t, ∞]. This means
that all connects and disconnects that finished before t are guaranteed
to already be applied in this configuration. Newer connects and
disconnects that finished after t might also already be applied.
A DisconnectBeforeOperationCompleteError if this
controller disconnected before the cluster configuration could be
retrieved.
An OperationNotSupportedInCurrentConnectionStateError
if this controller is not connected to the Raft cluster, this.connect()
needs to be called first.
Returns a promise resolving to the state of the RSM. The state is
retrieved by proposing a NOOP and waiting for its resulting state. The
NOOP is being proposed internally and therefore cannot be observed by
observeState().
A promise resolving to the state of the RSM. The state will be
of type RaftData.
The returned state is guaranteed to be up to date or newer
respective to the point in time when this function was called. In other
words calling getState() at time t will return the distributed state
from some point in time inside [t, ∞]. This means that all inputs
committed before t are guaranteed to already be applied in this state.
Newer inputs that were committed after t might also already be applied.
A DisconnectBeforeOperationCompleteError if this
controller is disconnected from the cluster before the state could be
retrieved.
An OperationNotSupportedInCurrentConnectionStateError
if this controller is not connected to the Raft cluster, this.connect()
needs to be called first.
Returns an observable that emits the cluster configuration on every
configuration change as soon as the change becomes known to this
controller. Cluster configuration changes are triggered when a
RaftController connects to or disconnects from the Raft cluster.
The returned observable completes and its subscriptions are automatically unsubscribed once the controller is disconnected or stopped, in order to release system resources and to avoid memory leaks.
an observable emitting the cluster configuration on every
configuration change. The cluster configuration contains the ids of all
RaftControllers in the cluster.
An OperationNotSupportedInCurrentConnectionStateError
if this controller is not connected to the Raft cluster, this.connect()
needs to be called first.
Returns an observable that emits the state of the RSM on every state update as soon as the update becomes known to this controller. State updates are triggered when a new input is committed.
The returned observable completes and its subscriptions are automatically unsubscribed once the controller is disconnected or stopped, in order to release system resources and to avoid memory leaks.
an observable emitting the state of the RSM on every state
update. The emitted state will be of type RaftData.
An OperationNotSupportedInCurrentConnectionStateError
if this controller is not connected to the Raft cluster, this.connect()
needs to be called first.
Proposes the given input to Raft. Raft will try to add the input to a
log shared between all RaftControllers in the Raft cluster. If the
input is accepted into the log it counts as committed and is applied to
the RSM. The returned promise resolves to the resulting state of the RSM
after the proposed input has been applied.
A majority of controllers need to give their consent before the given input is accepted into the log. This might take indefinitely if no majority can be reached, e.g. if too many agents have crashed and cannot recover. In this case the returned promise is never resolved or rejected.
Input that should be committed and applied to the RSM. Has
to be of type RaftData.
A promise resolving to the resulting state of the RSM after the
proposed input has been applied if it ever gets applied. Is of type
RaftData. Is rejected if this RaftController is stopped or
disconnected before it could make sure that the input was committed. The
input might still be committed.
This function implements reproposed inputs as explained inside the Raft thesis. Manual reproposing by the user is not intended. That is why the returned promise never times out.
The object structure of input and resulting state can be chosen
by the user and depends on the implementation of the RSM that is provided
in the RaftControllerOptions of this controller. Both input
and resulting state have to be of type RaftData.
A TooManyQueuedUpInputProposalsError if there are
more than 1000 input proposals queued up that haven't been committed yet.
A DisconnectBeforeOperationCompleteError if this
controller is disconnected from the cluster before it could make sure
that the proposed input was committed.
An OperationNotSupportedInCurrentConnectionStateError
if this controller is not connected to the Raft cluster, this.connect()
needs to be called first.
Stops this RaftController WITHOUT disconnecting from the Raft cluster
and WITHOUT deleting the persisted state. Users of this RaftController
need to wait til the returned promise is resolved before they can
shutdown the corresponding Coaty container.
Users can use this function instead of disconnect() if they want to
shutdown this controller for some time without losing the current shared
state and cluster configuration. This might be useful if e.g. the entire
cluster has to shutdown for a few days but its state and configuration
should be preserved. stop() can also be seen as a graceful crash.
A promise that resolves once this RaftController has been
stopped.
If at least half of all RaftControllers in the Raft cluster are
stopped the cluster can no longer make any progress til enough stopped
controllers reconnect using connect().
An OperationNotSupportedInCurrentConnectionStateError
if this controller is currently in the process of connecting or
disconnecting.
Protected getCan be overwritten to change the RaftCommunication
implementation used by Raft.
Protected getCan be overwritten to change the RaftPersistency
implementation used by Raft.
The default implementation persists Raft data using Coaty's SQL-based
local storage in the form of a local SQLite database file. This database
must be referenced in Coaty Configuration.databaseOptions under the key
specified by RaftControllerOptions.databaseKey (or "raftdb" if not
specified) using the adapter named "SqLiteNodeAdapter". Make sure the
path to the database file (i.e. connectionString) exists and is
accessible.
Internal
For internal use in framework only.
Never instantiate Controller objects in your application; they are created automatically by dependency injection.
Gets the container's communication manager.
Gets the container object of this controller.
Gets the controller's options as specified in the configuration options.
Gets the registered name of this controller.
The registered name is either defined by the corresponding key in the
Components.controllers object in the container configuration, or by
invoking Container.registerController method with this name.
Gets the container's Runtime object.
Protected extendWhenever one of the controller's log methods (e.g. logDebug, logInfo,
logWarning, logError, logFatal) is called by application code, the
controller creates a Log object with appropriate property values and
passes it to this method before advertising it.
You can override this method to additionally set certain properties (such
as LogHost.hostname or Log.logLabels). Ensure that
super.extendLogObject is called in your override. The base method does
nothing.
log object to be extended before being advertised
Called when the container has completely set up and injected all dependency components, including all its controllers.
Override this method to perform initializations in your custom controller
class instead of defining a constructor. Although the base implementation
does nothing it is good practice to call super.onInit() in your
override method; especially if your custom controller class does not
extend from the base Controller class directly.
Generated using TypeDoc
Maintains a replicated state machine (RSM) with other
RaftControllerinstances in the Coaty network using the Raft protocol. For that eachRaftControllerjoins a specified Raft cluster. An instance of the RSM in form of aRaftStateMachinehas to be provided in theRaftControllerOptionswhen bootstrapping this controller.A new
RaftControllerinstance needs toconnect()to the Raft cluster before it can modify/access the replicated state with the following functions:propose(input)proposes a new input that should be applied to the RSM.getState()returns the state of the RSM.observeState()returns an observable emitting on every RSM change.After a
RaftControllerhas connected to the Raft cluster it can monitor the cluster configuration with the following functions:getClusterConfiguration()returns the cluster configuration.observeClusterConfiguration()returns an observable emitting on every cluster configuration change.Before shutting down the Coaty container of this
RaftControllerthe user has to eitherdisconnect()from the Raft cluster orstop()this controller.