statemachine

package
v0.0.0-...-a582c34 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 16, 2021 License: Apache-2.0 Imports: 2 Imported by: 0

Documentation

Overview

Package statemachine contains the definitions of the IStateMachine and IOnDiskStateMachine interfaces for supporting the replicated state machine approach.

User services are provided with fault tolerance when they are implemented as IStateMachine or IOnDiskStateMachine instances. The Update method is used for update operations for the services, the Lookup method is used for handling read only queries to the services, snapshot related methods, including PrepareSnapshot, SaveSnapshot and RecoverFromSnapshot, are used to update service state based on snapshots.

Index

Constants

View Source
const (
	// RegularStateMachine is the state machine type that implements
	// IStateMachine.
	RegularStateMachine = 1
	// ConcurrentStateMachine is the state machine type that implements
	// IConcurrentStateMachine
	ConcurrentStateMachine = 2
	// OnDiskStateMachine is the state machine type that implements
	// IOnDiskStateMachine
	OnDiskStateMachine = 3
)

Variables

View Source
var (
	// ErrSnapshotStreaming is the error returned when the snapshot data being
	// generated can not be streamed to its intended destination.
	ErrSnapshotStreaming = errors.New("failed to stream the snapshot")
	// ErrOpenStopped is the error returned by the Open method of an
	// IOnDiskStateMachine type when it chooses to abort from its Open method.
	ErrOpenStopped = errors.New("open method did not complete")
)
View Source
var (
	// ErrSnapshotStopped is returned by state machine's SaveSnapshot and
	// RecoverFromSnapshot methods to indicate that those two snapshot operations
	// have been aborted as the associated raft node is being closed.
	ErrSnapshotStopped = errors.New("snapshot stopped")
	// ErrSnapshotAborted is returned by state machine's SaveSnapshot method to
	// indicate that the SaveSnapshot operation is aborted by the user.
	ErrSnapshotAborted = errors.New("snapshot aborted")
)
View Source
var (
	// ErrNotImplemented indicates that the requested optional feature is not
	// implemented by the state machine.
	ErrNotImplemented = errors.New("requested feature not implemented")
)

Functions

This section is empty.

Types

type CreateConcurrentStateMachineFunc

type CreateConcurrentStateMachineFunc func(uint64, uint64) IConcurrentStateMachine

CreateConcurrentStateMachineFunc is a factory function type for creating an IConcurrentStateMachine instance.

type CreateOnDiskStateMachineFunc

type CreateOnDiskStateMachineFunc func(clusterID uint64, nodeID uint64) IOnDiskStateMachine

CreateOnDiskStateMachineFunc is a factory function type for creating IOnDiskStateMachine instances.

type CreateStateMachineFunc

type CreateStateMachineFunc func(clusterID uint64, nodeID uint64) IStateMachine

CreateStateMachineFunc is a factory function type for creating IStateMachine instances.

type Entry

type Entry struct {
	// Index is the Raft log index of the entry. The field is set by the
	// Dragonboat library and it is strictly read-only.
	Index uint64
	// Cmd is the proposed command. This field is strictly read-only.
	Cmd []byte
	// Result is the result value obtained from the Update method of an
	// IConcurrentStateMachine or IOnDiskStateMachine instance.
	Result Result
}

Entry represents a Raft log entry that is going to be provided to the Update method of an IConcurrentStateMachine or IOnDiskStateMachine instance.

type IConcurrentStateMachine

type IConcurrentStateMachine interface {
	// Update updates the IConcurrentStateMachine instance. The input Entry slice
	// is list of continuous proposed and committed commands from clients, they
	// are provided together as a batch so the IConcurrentStateMachine
	// implementation can choose to batch them and apply together to hide latency.
	//
	// The Update method must be deterministic, meaning that given the same initial
	// state of IConcurrentStateMachine and the same input sequence, it should
	// reach to the same updated state and outputs the same returned results. The
	// input entry slice should be the only input to this method. Reading from
	// the system clock, random number generator or other similar external data
	// sources will violate the deterministic requirement of the Update method.
	//
	// The IConcurrentStateMachine implementation should not keep a reference to
	// the input entry slice after return.
	//
	// Update returns the input entry slice with the Result field of all its
	// members set.
	//
	// Update returns an error when there is unrecoverable error for updating the
	// on disk state machine, e.g. disk failure when trying to update the state
	// machine.
	Update([]Entry) ([]Entry, error)
	// Lookup queries the state of the IConcurrentStateMachine instance and
	// returns the query result as a byte slice. The input byte slice specifies
	// what to query, it is up to the IConcurrentStateMachine implementation to
	// interpret the input byte slice.
	//
	// When an error is returned by the Lookup() method, the error will be passed
	// to the caller of NodeHost's ReadLocalNode() or SyncRead() methods to be
	// handled. A typical scenario for returning an error is that the state
	// machine has already been closed or aborted from a RecoverFromSnapshot
	// procedure when Lookup is being handled.
	//
	// The IConcurrentStateMachine implementation should not keep a reference of
	// the input byte slice after return.
	//
	// The Lookup() method is a read only method, it should never change the state
	// of the IConcurrentStateMachine instance.
	Lookup(interface{}) (interface{}, error)
	// PrepareSnapshot prepares the snapshot to be concurrently captured and saved.
	// PrepareSnapshot is invoked before SaveSnapshot is called and it is invoked
	// with mutual exclusion protection from the Update method.
	//
	// PrepareSnapshot in general saves a state identifier of the current state,
	// such state identifier is usually a version number, a sequence number, a
	// change ID or some other in memory small data structure used for describing
	// the point in time state of the state machine. The state identifier is
	// returned as an interface{} and it is provided to the SaveSnapshot() method
	// so the state machine state at that identified point in time can be saved
	// when SaveSnapshot is invoked.
	//
	// PrepareSnapshot returns an error when there is unrecoverable error for
	// preparing the snapshot.
	PrepareSnapshot() (interface{}, error)
	// SaveSnapshot saves the point in time state of the IConcurrentStateMachine
	// identified by the input state identifier to the provided io.Writer backed
	// by a file on disk and the provided ISnapshotFileCollection instance. This
	// is a read only method that should never change the state of the
	// IConcurrentStateMachine instance.
	//
	// It is important to understand that SaveSnapshot should never save the
	// current latest state. The point in time state identified by the input state
	// identifier is what suppose to be saved, the latest state might be different
	// from such specified point in time state as the state machine might have
	// already been updated by the Update() method after the completion of
	// the call to PrepareSnapshot.
	//
	// It is SaveSnapshot's responsibility to free the resources owned by the
	// input state identifier when it is done.
	//
	// The ISnapshotFileCollection instance is used to record finalized external
	// files that should also be included as a part of the snapshot. All other
	// state data should be saved into the io.Writer backed by snapshot file on
	// disk. It is application's responsibility to save the complete state so
	// that the recovered IConcurrentStateMachine state is considered as
	// identical to the original state.
	//
	// The provided read-only chan struct{} is to notify the SaveSnapshot method
	// that the associated Raft node is being closed so the IConcurrentStateMachine
	// can choose to abort the SaveSnapshot procedure and return
	// ErrSnapshotStopped immediately.
	//
	// SaveSnapshot is allowed to abort the snapshotting operation at any time by
	// returning ErrSnapshotAborted.
	//
	// SaveSnapshot returns the encountered error when generating the snapshot.
	// Other than the above mentioned ErrSnapshotStopped and ErrSnapshotAborted
	// errors, the IConcurrentStateMachine implementation should only return a
	// non-nil error when the system need to be immediately halted for critical
	// errors, e.g. disk error preventing you from saving the snapshot.
	SaveSnapshot(interface{},
		io.Writer, ISnapshotFileCollection, <-chan struct{}) error
	// RecoverFromSnapshot recovers the state of the IConcurrentStateMachine
	// instance from a previously saved snapshot captured by the SaveSnapshot()
	// method. The saved snapshot is provided as an io.Reader backed by a file
	// on disk together with a list of files previously recorded into the
	// ISnapshotFileCollection in SaveSnapshot().
	//
	// Dragonboat ensures that Update() and Close() will not be invoked when
	// RecoverFromSnapshot() is in progress.
	//
	// The provided read-only chan struct{} is provided to notify the
	// RecoverFromSnapshot() method that the associated Raft node is being closed.
	// On receiving such notification, RecoverFromSnapshot() can choose to
	// abort recovering from the snapshot and return an ErrSnapshotStopped error
	// immediately. Other than ErrSnapshotStopped, IConcurrentStateMachine should
	// only return a non-nil error when the system need to be immediately halted
	// for non-recoverable error, e.g. disk error preventing you from reading the
	// complete saved snapshot.
	//
	// RecoverFromSnapshot is invoked when restarting from a previously saved
	// state or when the Raft node is significantly behind its leader.
	RecoverFromSnapshot(io.Reader, []SnapshotFile, <-chan struct{}) error
	// Close closes the IConcurrentStateMachine instance.
	//
	// The Close method is not allowed to update the state of the
	// IConcurrentStateMachine visible to the Lookup() method.
	//
	// Close allows the application to finalize resources to a state easier to
	// be re-opened and used in the future. It is important to understand that
	// Close is not guaranteed to be always called, e.g. node might crash at any
	// time. IConcurrentStateMachine should be designed in a way that the
	// safety and integrity of its managed data doesn't rely on whether the Close
	// method is called or not.
	//
	// Other than setting up some internal flags to indicate that the
	// IConcurrentStateMachine instance has been closed, the Close method is not
	// allowed to update the state of IConcurrentStateMachine visible to the
	// Lookup method.
	Close() error
}

IConcurrentStateMachine is the interface to be implemented by application's state machine when concurrent access to the state machine is required. For a typical IConcurrentStateMachine type, most of its managed data is expected to be fitted into memory, Dragonboat manages its captured snapshots and saved Raft Logs to ensure such in-memory state machine state can be restored after reboot.

The Update method is always invoked from the same goroutine. The Lookup, SaveSnapshot and GetHash methods can be invoked concurrent to the Update method. The Lookup method is also allowed to be invoked concurrent to the RecoverFromSnapshot method. It is user's responsibility to implement the IConcurrentStateMachine instance with such supported concurrency while also protecting the state machine data integrity. Invocations to the Update, PrepareSnapshot, RecoverFromSnapshot and the Close methods are guarded by the system to ensure mutual exclusion.

When created, an IConcurrentStateMachine instance should always start from an empty state. Dragonboat will use saved snapshots and Raft Logs to help a restarted IConcurrentStateMachine instance to catch up to its previous state.

IConcurrentStateMachine is provided as an alternative option to the IStateMachine interface which also keeps state machine data mostly in memory but without concurrent access support. Users are recommended to use the IStateMachine interface whenever possible.

type IExtended

type IExtended interface {
	// NALookup is similar to user state machine's Lookup method, it tries to
	// minimize extra heap allocation by taking a byte slice as the input and the
	// returned query result is also provided as a byte slice. The input byte
	// slice specifies what to query, it is up to the implementation to interpret
	// the input byte slice.
	//
	// Lookup method is a read-only method, it should never change state machine's
	// state.
	NALookup([]byte) ([]byte, error)
}

IExtended is an optional interface to be implemented by a user state machine type, most of its member methods are for performance optimization purposes.

type IHash

type IHash interface {
	// GetHash returns a uint64 value used to represent the current state of the
	// state machine. The hash should be generated in a deterministic manner
	// which means nodes from the same Raft cluster are suppose to return the
	// same hash result when they have the same Raft Log entries applied.
	//
	// GetHash is a read-only operation.
	GetHash() (uint64, error)
}

IHash is an optional interface to be implemented by a user state machine type when the ability to generate state machine hash is required.

type IOnDiskStateMachine

type IOnDiskStateMachine interface {
	// Open opens the existing on disk state machine to be used or it creates a
	// new state machine with empty state if it does not exist. Open returns the
	// most recent index value of the Raft log that has been persisted, or it
	// returns 0 when the state machine is a new one.
	//
	// The provided read only chan struct{} channel is used to notify the Open
	// method that the node has been stopped and the Open method can choose to
	// abort by returning an ErrOpenStopped error.
	//
	// Open is called shortly after the Raft node is started. The Update method
	// and the Lookup method will not be called before the completion of the Open
	// method.
	Open(stopc <-chan struct{}) (uint64, error)
	// Update updates the IOnDiskStateMachine instance. The input Entry slice
	// is a list of continuous proposed and committed commands from clients, they
	// are provided together as a batch so the IOnDiskStateMachine implementation
	// can choose to batch them and apply together to hide latency. Update returns
	// the input entry slice with the Result field of all its members set.
	//
	// The read only Index field of each input Entry instance is the Raft log
	// index of each entry, it is IOnDiskStateMachine's responsibility to
	// atomically persist the Index value together with the corresponding state
	// update.
	//
	// The Update method can choose to synchronize all of its in-core state with
	// that on disk. This can minimize the number of committed Raft entries that
	// need to be re-applied after reboot. Update can also choose to postpone such
	// synchronization until the Sync method is invoked, this approach produces
	// higher throughput during fault free running at the cost that some of the
	// most recent Raft entries not synchronized onto disks will have to be
	// re-applied after reboot.
	//
	// When the Update method does not synchronize its in-core state with that on
	// disk, the implementation must ensure that after a reboot there is no
	// applied entry in the State Machine more recent than any entry that was
	// lost during reboot. For example, consider a state machine with 3 applied
	// entries, let's assume their index values to be 1, 2 and 3. Once they have
	// been applied into the state machine without synchronizing the in-core state
	// with that on disk, it is okay to lose the data associated with the applied
	// entry 3, but it is strictly forbidden to have the data associated with the
	// applied entry 3 available in the state machine while the one with index
	// value 2 got lost during reboot.
	//
	// The Update method must be deterministic, meaning given the same initial
	// state of IOnDiskStateMachine and the same input sequence, it should reach
	// to the same updated state and outputs the same results. The input entry
	// slice should be the only input to this method. Reading from the system
	// clock, random number generator or other similar external data sources will
	// likely violate the deterministic requirement of the Update method.
	//
	// Concurrent calls to the Lookup method and the SaveSnapshot method are not
	// blocked when the state machine is being updated by the Update method.
	//
	// The IOnDiskStateMachine implementation should not keep a reference to the
	// input entry slice after return.
	//
	// Update returns an error when there is unrecoverable error when updating the
	// on disk state machine.
	Update([]Entry) ([]Entry, error)
	// Lookup queries the state of the IOnDiskStateMachine instance and returns
	// the query result as an interface{}. The input interface{} specifies what to
	// query, it is up to the IOnDiskStateMachine implementation to interpret such
	// input. The returned interface{} contains the query result.
	//
	// When an error is returned by the Lookup method, the error will be passed
	// to the caller to be handled. A typical scenario for returning an error is
	// that the state machine has already been closed or aborted from a
	// RecoverFromSnapshot procedure before Lookup is called.
	//
	// Concurrent calls to the Update and RecoverFromSnapshot method are not
	// blocked when calls to the Lookup method are being processed.
	//
	// The IOnDiskStateMachine implementation should not keep any reference of
	// the input interface{} after return.
	//
	// The Lookup method is a read only method, it should never change the state
	// of IOnDiskStateMachine.
	Lookup(interface{}) (interface{}, error)
	// Sync synchronizes all in-core state of the state machine to persisted
	// storage so the state machine can continue from its latest state after
	// reboot.
	//
	// Sync is always invoked with mutual exclusion protection from the Update,
	// PrepareSnapshot, RecoverFromSnapshot and Close methods.
	//
	// Sync returns an error when there is unrecoverable error for synchronizing
	// the in-core state.
	Sync() error
	// PrepareSnapshot prepares the snapshot to be concurrently captured and
	// streamed. PrepareSnapshot is invoked before SaveSnapshot is called and it
	// is always invoked with mutual exclusion protection from the Update, Sync,
	// RecoverFromSnapshot and Close methods.
	//
	// PrepareSnapshot in general saves a state identifier of the current state,
	// such state identifier can be a version number, a sequence number, a change
	// ID or some other small in memory data structure used for describing the
	// point in time state of the state machine. The state identifier is returned
	// as an interface{} before being passed to the SaveSnapshot() method.
	//
	// PrepareSnapshot returns an error when there is unrecoverable error for
	// preparing the snapshot.
	PrepareSnapshot() (interface{}, error)
	// SaveSnapshot saves the point in time state of the IOnDiskStateMachine
	// instance identified by the input state identifier, which is usually not
	// the latest state of the IOnDiskStateMachine instance, to the provided
	// io.Writer.
	//
	// It is application's responsibility to save the complete state to the
	// provided io.Writer in a deterministic manner. That is for the same state
	// machine state, when SaveSnapshot is invoked multiple times with the same
	// input state identifier, the content written to the provided io.Writer
	// should always be the same.
	//
	// When there is any connectivity error between the local node and the remote
	// node, an ErrSnapshotStreaming will be returned by io.Writer's Write method.
	// The SaveSnapshot method should return ErrSnapshotStreaming to abort its
	// operation.
	//
	// It is SaveSnapshot's responsibility to free the resources owned by the
	// input state identifier when it is done.
	//
	// The provided read-only chan struct{} is provided to notify the SaveSnapshot
	// method that the associated Raft node is being closed so the
	// IOnDiskStateMachine can choose to abort the SaveSnapshot procedure and
	// return ErrSnapshotStopped immediately.
	//
	// SaveSnapshot is allowed to abort the snapshotting operation at any time by
	// returning ErrSnapshotAborted.
	//
	// The SaveSnapshot method is allowed to be invoked when there is concurrent
	// call to the Update method. SaveSnapshot is a read-only method, it should
	// never change the state of the IOnDiskStateMachine.
	//
	// SaveSnapshot returns the encountered error when generating the snapshot.
	// Other than the above mentioned ErrSnapshotStopped and ErrSnapshotAborted
	// errors, the IOnDiskStateMachine implementation should only return a non-nil
	// error when the system need to be immediately halted for critical errors,
	// e.g. disk error preventing you from saving the snapshot.
	SaveSnapshot(interface{}, io.Writer, <-chan struct{}) error
	// RecoverFromSnapshot recovers the state of the IOnDiskStateMachine instance
	// from a snapshot captured by the SaveSnapshot() method on a remote node. The
	// saved snapshot is provided as an io.Reader backed by a file stored on disk.
	//
	// Dragonboat ensures that the Update, Sync, PrepareSnapshot, SaveSnapshot and
	// Close methods will not be invoked when RecoverFromSnapshot() is in
	// progress.
	//
	// The provided read-only chan struct{} is provided to notify the
	// RecoverFromSnapshot method that the associated Raft node has been closed.
	// On receiving such notification, RecoverFromSnapshot() can choose to
	// abort recovering from the snapshot and return an ErrSnapshotStopped error
	// immediately. Other than ErrSnapshotStopped, IOnDiskStateMachine should
	// only return a non-nil error when the system need to be immediately halted
	// for non-recoverable error.
	//
	// RecoverFromSnapshot is not required to synchronize its recovered in-core
	// state with that on disk.
	RecoverFromSnapshot(io.Reader, <-chan struct{}) error
	// Close closes the IOnDiskStateMachine instance. Close is invoked when the
	// state machine is in a ready-to-exit state in which there will be no further
	// call to the Update, Sync, PrepareSnapshot, SaveSnapshot and the
	// RecoverFromSnapshot method. It is possible to have concurrent Lookup calls,
	// Lookup can also be called after the return of Close.
	//
	// Close allows the application to finalize resources to a state easier to
	// be re-opened and restarted in the future. It is important to understand
	// that Close is not guaranteed to be always invoked, e.g. node can crash at
	// any time without calling the Close method. IOnDiskStateMachine should be
	// designed in a way that the safety and integrity of its on disk data
	// doesn't rely on whether Close is eventually called or not.
	//
	// Other than setting up some internal flags to indicate that the
	// IOnDiskStateMachine instance has been closed, the Close method is not
	// allowed to update the state of IOnDiskStateMachine visible to the outside.
	Close() error
}

IOnDiskStateMachine is the interface to be implemented by application's state machine when the state machine state is always persisted on disks. IOnDiskStateMachine basically matches the state machine type described in the section 5.2 of the Raft thesis.

For IOnDiskStateMachine types, concurrent access to the state machine is supported. An IOnDiskStateMachine type allows its Update method to be concurrently invoked when there are ongoing calls to the Lookup or the SaveSnapshot method. Lookup is also allowed when the RecoverFromSnapshot or the Close methods are being invoked. Invocations to the Update, Sync, PrepareSnapshot, RecoverFromSnapshot and Close methods are guarded by the system to ensure mutual exclusion.

Once created, the Open method is immediately invoked to open and use the persisted state on disk. This makes IOnDiskStateMachine different from IStateMachine types which require the state machine state to be fully reconstructed from saved snapshots and Raft logs.

Applications that implement IOnDiskStateMachine are recommended to setup periodic snapshotting with relatively short time intervals, that triggers the state machine's metadata, usually only a few KBytes each, to be periodically snapshotted and thus causes negligible overheads for the system. It also provides opportunities for the system to signal Raft Log compactions to free up disk spaces.

type ISnapshotFileCollection

type ISnapshotFileCollection interface {
	// AddFile adds an external file to the snapshot being currently generated.
	// The file must has been finalized meaning its content will not change in
	// the future. It is your application's responsibility to make sure that the
	// file being added can be accessible from the current process and it is
	// possible to create a hard link to it from the NodeHostDir directory
	// specified in NodeHost's NodeHostConfig. The file to be added is identified
	// by the specified fileID. The metadata byte slice is the metadata of the
	// file being added, it can be the checksum of the file, file type, file name,
	// other file hierarchy information, or a serialized combination of such
	// metadata.
	AddFile(fileID uint64, path string, metadata []byte)
}

ISnapshotFileCollection is the interface used by the IStateMachine.SaveSnapshot() method for recording external files that should be included as a part of the snapshot being created.

For example, consider you have a IStateMachine implementation internally backed by a NoSQL DB, when creating a snapshot of the IStateMachine instance, the state of the NoSQL DB need to be captured and saved as well. When the NoSQL has its own built-in feature to snapshot the current state into some on-disk files, these files should be included in IStateMachine's snapshot so they can be used to reconstruct the current state of the NoSQL DB when the IStateMachine instance recovers from the saved snapshot.

type IStateMachine

type IStateMachine interface {
	// Update updates the IStateMachine instance. The input data slice is the
	// proposed command from client, it is up to the IStateMachine implementation
	// to interpret this byte slice and update the IStateMachine instance
	// accordingly.
	//
	// The Update method must be deterministic, meaning given the same initial
	// state of IStateMachine and the same input, it should always reach to the
	// same updated state and outputs the same returned value. This requires the
	// input byte slice should be the only input to this method. Reading from
	// system clock, random number generator or other similar data sources will
	// likely violate the deterministic requirement of the Update method.
	//
	// The IStateMachine implementation should not keep a reference to the input
	// byte slice after return.
	//
	// Update returns a Result value used to indicate the outcome of the update
	// operation. An error is returned when there is unrecoverable error, such
	// error will cause the program to panic.
	Update([]byte) (Result, error)
	// Lookup queries the state of the IStateMachine instance. The input
	// interface{} specifies what to query, it is up to the IStateMachine
	// implementation to interpret such input interface{}. The returned
	// interface{} is the query result provided by the IStateMachine
	// implementation.
	//
	// The IStateMachine implementation should not keep a reference of the input
	// interface{} after return. The Lookup method is a read only method, it
	// should never change the state of IStateMachine.
	//
	// When an error is returned by the Lookup method, it will be passed to the
	// user client.
	Lookup(interface{}) (interface{}, error)
	// SaveSnapshot saves the current state of the IStateMachine instance to the
	// provided io.Writer backed by an on disk file. SaveSnapshot is a read only
	// operation.
	//
	// The data saved into the io.Writer is usually the in-memory data, while the
	// ISnapshotFileCollection instance is used to record immutable files that
	// should also be included as a part of the snapshot. It is application's
	// responsibility to save the complete state so that the reconstructed
	// IStateMachine state based on such saved snapshot will be considered as
	// identical to the original state.
	//
	// The provided read-only chan struct{} is used to notify that the associated
	// Raft node is being closed so the implementation can choose to abort the
	// SaveSnapshot procedure and return ErrSnapshotStopped immediately.
	//
	// SaveSnapshot is allowed to abort the snapshotting operation at any time by
	// returning ErrSnapshotAborted.
	//
	// Other than the above mentioned ErrSnapshotStopped and ErrSnapshotAborted
	// errors, the IStateMachine implementation should only return a non-nil error
	// when the system need to be immediately halted for critical errors, e.g.
	// disk error preventing you from saving the snapshot.
	SaveSnapshot(io.Writer, ISnapshotFileCollection, <-chan struct{}) error
	// RecoverFromSnapshot recovers the state of an IStateMachine instance from a
	// previously saved snapshot captured by the SaveSnapshot method. The saved
	// snapshot is provided as an io.Reader backed by an on disk file and
	// a list of immutable files previously recorded into the
	// ISnapshotFileCollection by the SaveSnapshot method.
	//
	// The provided read-only chan struct{} is used to notify the
	// RecoverFromSnapshot() method that the associated Raft node is being closed.
	// On receiving such notification, RecoverFromSnapshot() can choose to
	// abort and return ErrSnapshotStopped immediately. Other than
	// ErrSnapshotStopped, IStateMachine should only return a non-nil error when
	// the system must be immediately halted for non-recoverable error, e.g. disk
	// error preventing you from reading the complete saved snapshot.
	RecoverFromSnapshot(io.Reader, []SnapshotFile, <-chan struct{}) error
	// Close closes the IStateMachine instance.
	//
	// The Close method is not allowed to update the state of the IStateMachine
	// visible to IStateMachine's Lookup method.
	//
	// This allows the application to finalize resources to a state easier to be
	// re-opened and used in the future. It is important to understand that Close
	// is not guaranteed to be always called, e.g. node might crash at any time.
	// IStateMachine should be designed in a way that the safety and integrity of
	// its managed data doesn't rely on whether the Close method is called or not.
	Close() error
}

IStateMachine is the interface to be implemented by application's state machine when most of the state machine data is stored in memory. It is the basic state machine type described in the Raft thesis.

A sync.RWMutex is used internally by dragonboat as a reader/writer mutual exclusion lock to guard the IStateMachine instance when accessing IStateMachine's member methods. The Update, RecoverFromSnapshot and Close methods are invoked when the write lock is acquired, other methods are invoked when the shared read lock is acquired.

As the state is mostly in memory, snapshots are usually periodically captured to save its state to disk. After each reboot, IStateMachine state must be reconstructed from the empty state based on the latest snapshot and saved Raft logs.

When created, an IStateMachine instance should always start from an empty state. Saved snapshots and Raft logs will be used to help a rebooted IStateMachine instance to catch up to its previous state.

type Result

type Result struct {
	// Value is a 64 bits integer value used to indicate the outcome of the
	// update operation.
	Value uint64
	// Data is an optional byte slice created and returned by the update
	// operation. It is useful for CompareAndSwap style updates in which an
	// arbitrary length of bytes need to be returned.
	// Users are strongly recommended to use the query methods supported by
	// NodeHost to query the state of their IStateMachine and IOnDiskStateMachine
	// types, proposal based queries are known to work but are not recommended.
	Data []byte
}

Result is the result type generated and returned by the Update method in IStateMachine and IOnDiskStateMachine types.

type SnapshotFile

type SnapshotFile struct {
	// FileID is the ID of the file provided to ISnapshotFileCollection.AddFile().
	FileID uint64
	// Filepath is the current full path of the file.
	Filepath string
	// Metadata is the metadata provided to ISnapshotFileCollection.AddFile().
	Metadata []byte
}

SnapshotFile is the struct used to describe external files included in a snapshot.

type Type

type Type uint64

Type is the state machine type.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL