Interface AsyncSnapshot


public interface AsyncSnapshot
Optional interface for state machines that support non-blocking snapshot creation.

A StateMachine that also implements this interface opts into a two-phase snapshot lifecycle: a fast capture phase (prepareSnapshot()) that freezes a consistent view of the state, followed by a slow serialization phase (SnapshotHandle.writeTo(java.io.DataOutput)) that runs without blocking new commits from being applied.

State machines that do not implement this interface continue to use the synchronous StateMachine.writeContentTo(java.io.DataOutput) path, which blocks commits until serialization completes.

Consistency Contract

The implementation is solely responsible for ensuring the SnapshotHandle returned by prepareSnapshot() is immune to concurrent state mutations. The framework does NOT provide any isolation. It resumes applying commits immediately after prepareSnapshot() returns.

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

    Modifier and Type
    Method
    Description
    Captures a point-in-time consistent view of the state machine.
    void
    Restores the state machine from a snapshot stream.
  • Method Details

    • prepareSnapshot

      SnapshotHandle prepareSnapshot() throws Exception
      Captures a point-in-time consistent view of the state machine.

      The returned SnapshotHandle represents a frozen, immutable view of the state machine at the moment this method returns. The state machine may continue to receive StateMachine.apply(byte[], int, int, boolean) calls after this method returns. The returned handle must not be affected by subsequent mutations. This guarantee is up to the implementer, not complying leads to the creation of snapshot with an undefined state.

      This method must return quickly. Expensive work, such as serialization, I/O, compression, belongs in SnapshotHandle.writeTo(java.io.DataOutput), not here. This method serves as only a mechanism to prepare the underlying state machine for a read of a point in time.

      Consistency Guarantee

      The implementation is responsible for ensuring the returned handle is immune to concurrent mutations. Typical strategies include capturing a reference to a copy-on-write structure, deep-copying the state, or obtaining a database snapshot handle (e.g., RocksDB, LMDB). Observe that performing a deep-copy of a very large object is an expensive operation that could stall progress.

      Failures

      If this method throws, no snapshot is created and SnapshotHandle.release() is not called. The framework retries on the next snapshot threshold. The lack of snapshot could render some nodes effectively unavailable since they can't commit newer requests.

      Returns:
      a handle to the frozen state, never null
      Throws:
      Exception - if the snapshot cannot be prepared
    • readContentFrom

      void readContentFrom(DataInput in)
      Restores the state machine from a snapshot stream.

      Replaces the entire state machine contents with the state serialized by a prior SnapshotHandle.writeTo(java.io.DataOutput) call. The implementation must completely read the stream and restore its internal state deterministically before returning. The implementation may need to clear all existing state before populating from the stream.

      This method is never called concurrently with StateMachine.apply(byte[], int, int, boolean). No locking mechanism is needed.

      Failures

      If an exception is thrown, the state machine may be left in an inconsistent state. Implementations should ensure restoration is atomic or clearly document partial-failure behavior. The underlying mechanism will not retry or perform any cleanup login in case of exceptions. The Raft implementation assumes the recovery mechanism leaves a perfect state machine after restoration.

      Parameters:
      in - the input stream containing the serialized snapshot