fix(deps): update rust crate openraft to 0.9.0 #39

Open
renovate-bot wants to merge 1 commit from renovate/openraft-0.x into master
Member

This PR contains the following updates:

Package Type Update Change
openraft dependencies minor 0.8.8 -> 0.9.0

Release Notes

datafuselabs/openraft (openraft)

v0.9.17

Compare Source

Summary:

  • Improved:
    • 536a435e Chunk read log entry and check range on startup.
    • dc18dc6f remove Copy bound from NodeId.

Detail:

Improved:
  • Improved: 536a435e Chunk read log entry and check range on startup; by 张炎泼; 2024-09-14

    • Implement chunk-based reading of committed log entries when
      re-applying to state machine upon startup.

    • Add validation for log entry indexes, to avoid applying wrong entries
      to state machine.

  • Improved: dc18dc6f remove Copy bound from NodeId; by 张炎泼; 2024-10-14

    The NodeId type is currently defined as:

    type NodeId: .. + Copy + .. + 'static;
    

    This commit removes the Copy bound from NodeId.
    This modification will allow the use of non-Copy types as NodeId,
    providing greater flexibility for applications that prefer
    variable-length strings or other non-Copy types for node
    identification.

    This change maintain compatibility by updating derived Copy
    implementations with manual implementations:

    // Before
    #[derive(Copy...)]
    pub struct LogId<NID: NodeId> {}
    
    // After
    impl<NID: Copy> Copy for LogId<NID> {}
    

v0.9.16

Compare Source

What's Changed

Full Changelog: https://github.com/datafuselabs/openraft/compare/v0.9.15...v0.9.16

v0.9.15

Compare Source

Summary:

  • Fixed:
    • 0b1293f3 Should not update vote when seeing higher vote in RequestVote response.
    • 94b1e843 Clarify that receiving an equal vote does not grant leadership.
  • Added:
    • 5f5d7e9f Add TypeConfigExt to simplify RaftTypeConfig Access.

Detail:

Fixed:
  • Fixed: 0b1293f3 Should not update vote when seeing higher vote in RequestVote response; by 张炎泼; 2024-07-04

    This commit addresses an issue in the vote updating mechanism during the
    handling of RequestVote responses. Previously, encountering a higher
    vote in a response incorrectly led to an update of the local
    state.vote, which could break Raft consistency rules.

    Issue Description:

    • A higher vote seen in a RequestVote response does not necessarily
      mean that the vote is granted. The local state.vote should only be
      updated if the vote is actually granted, i.e., the responding node has
      a higher vote and a last_log_id that allows it to become a leader.

    Resolution:

    • The local state.vote will no longer be updated upon merely seeing a
      higher vote in the RequestVote response. Instead, this higher vote
      will be recorded in last_seen_vote for consideration in the next
      election cycle, without updating the current state.vote.

    This bug is introduced in: f0a9e34

  • Fixed: 94b1e843 Clarify that receiving an equal vote does not grant leadership.; by 张炎泼; 2024-08-28

    A node's vote may be updated when a leader observes a higher vote.
    In such cases, the leader updates its local vote and steps down.
    However, this vote update does not imply that the node accepts the
    higher vote as valid for leadership, as it has not yet compared their
    logs.

    In this commit, re-enable VoteResponse.vote_granted to indicate a vote
    is granted.

    This commit also fix:

Added:
  • Added: 5f5d7e9f Add TypeConfigExt to simplify RaftTypeConfig Access; by 张炎泼; 2024-07-03

    This commit introduces a new trait, TypeConfigExt, which extends
    RaftTypeConfig. The purpose of this trait is to simplify the access to
    various functionalities provided by the RaftTypeConfig trait,
    enhancing code readability and reducing complexity.

    Methods Added to TypeConfigExt:

    • now()
    • sleep()
    • sleep_until()
    • timeout()
    • timeout_at()
    • oneshot()
    • spawn()

    Usage Improvement:

    • Instead of using the
      <<C as RaftTypeConfig>::AsyncRuntime as AsyncRuntime>::Instant::now(),
      you can now simply call C::now().

v0.9.14

Compare Source

v0.9.13

Compare Source

Summary:

  • Added:
    • fb49efb3 Add DecomposeResult to simplify error handling.

Detail:

Added:
  • Added: fb49efb3 Add DecomposeResult to simplify error handling; by 张炎泼; 2024-06-20

    This commit treats remote errors occurring during RPC, like a Fatal
    error, as an Unreachable error. This is due to Openraft's current
    inability to distinguish between an unreachable node and a broken node.

    • Helper trait DecomposeResult: Introduced to simplify handling
      composite errors. It converts a result of the
      form Result<R, ErrorAOrB>
      into a nested result Result<Result<R, ErrorA>, ErrorB>.

v0.9.12

Compare Source

Summary:

  • DocFixed:
    • 1385394c RemoveNodes -> add_leaner in dynamic-membership.
  • Added:
    • 8cd00388 Add RaftLogReader::limited_get_log_entries().

Detail:

DocFixed:
  • DocFixed: 1385394c RemoveNodes -> add_leaner in dynamic-membership; by shuo; 2024-06-08
Added:
  • Added: 8cd00388 Add RaftLogReader::limited_get_log_entries(); by 张炎泼; 2024-06-16

    This commit adds the RaftLogReader::limited_get_log_entries() method,
    which enables applications to fetch log entries that are equal to or
    smaller than a specified range. This functionality is particularly
    useful for customizing the size of AppendEntries requests at the storage
    API level.

    • Applications can now decide the number of log entries to return based
      on the input range. If the application determines that the requested
      log entries range is too large for a single RPC, it can opt to return
      only the first several requested log entries instead of the full
      range.

    • The method provides a default implementation that delegates the
      operation to RaftLogReader::try_get_log_entries.

    This enhancement allows for more flexible and efficient handling of log
    entries, particularly in scenarios where network constraints or
    performance considerations require smaller data transfers.

v0.9.11

Compare Source

Summary:

  • Fixed:
    • 30cdf5fb New leader must flush blank log.

Detail:

Fixed:
  • Fixed: 30cdf5fb New leader must flush blank log; by 张炎泼; 2024-05-14

    This commit addresses a critical issue where if a new leader does not
    flush the blank log to disk upon becoming established and then restarts
    immediately, there is a possibility that previously committed data
    becomes invisible to readers.

    Before the blank log is flushed, the leader (identified by vote v3)
    assumes it will be flushed and commits this log once (|quorum|-1)
    replication responses are received. If the blank log is lost and the
    server is restarted, data committed by a new leader (vote v2) may
    not be visible.

    This issue is addressed by utilizing LeaderHandler::leader_append_entries()
    instead of ReplicationHandler::append_blank_log(), where the former
    does not wait for the blank log to flush.

    Changes:

    • When assigning log IDs to log entries, the Leading.last_log_id,
      which represents the state of the log proposer (equivalent term in
      Paxos is Proposer), should be used instead of RaftState.last_log_id,
      which represents the state of the log receiver (equivalent term in
      Paxos is Acceptor).

    • Consequently, the method assign_log_ids() has been moved from
      RaftState to Leading.

    • Avoid manual implementation of duplicated logic:

      • During initialize(), reuse FollowingHandler::do_append_entries()
        to submit the very first log to storage.

      • In establish_leader(), reuse
        LeaderHandler::leader_append_entries() to submit log to storage
        and remove ReplicationHandler::append_blank_log().

      • Remove Command::AppendEntry.

v0.9.10

Compare Source

Summary:

  • Improved:
    • 14f174e9 cancel passed to full_snapshot() should be static.

Detail:

Improved:
  • Improved: 14f174e9 cancel passed to full_snapshot() should be static; by 张炎泼; 2024-05-06

v0.9.9

Compare Source

Summary:

  • Fixed:
    • 8b62c797 Immediate response when snapshot installation is unnecessary.

Detail:

Fixed:
  • Fixed: 8b62c797 Immediate response when snapshot installation is unnecessary; by 张炎泼; 2024-05-05

    When Engine::handle_install_full_snapshot() is called and the provided
    snapshot is not up-to-date, the snapshot should not be installed, and
    the response should be sent back immediately. Previously, the method
    might delay the response unnecessarily, waiting for an installation
    process that would not proceed.

    This commit adjusts the logic so that if the snapshot is recognized as
    outdated, it immediately returns a None Condition, ensuring the
    caller is informed straightaway that no installation will occur.

v0.9.8

Compare Source

Summary:

  • Fixed:
    • fd5c657f Chunked should reset offset 0 when a SnapshotMismatch error is received.

Detail:

Fixed:
  • Fixed: fd5c657f Chunked should reset offset 0 when a SnapshotMismatch error is received; by 张炎泼; 2024-05-02

    When a SnapshotMismatch is received, the sending end should re-send
    all snapshot data from the beginning.

v0.9.7

Compare Source

Summary:

  • Fixed:
    • ff4cf8fe openraft-0.9.6 requires openraft-macros-0.9.6 or newer.

Detail:

Fixed:
  • Fixed: ff4cf8fe openraft-0.9.6 requires openraft-macros-0.9.6 or newer; by 张炎泼; 2024-04-25

v0.9.6

Compare Source

Summary:

  • Added:
    • 5776139d Add #[since(version="1.0")] to specify first version of a feature.
    • b172dc8e Add macro expand!() to expand a template.
  • Improved:
    • 99596c75 declare_raft_types allows the types in any order.
  • Fixed:
    • 14d42e4f Load mebmership since last_applied, not last_membership.index on startup.

Detail:

Added:
  • Added: 5776139d Add #[since(version="1.0")] to specify first version of a feature; by 张炎泼; 2024-04-12

    #[since(version = "1.0.0")] adds a doc line /// Since: Version(1.0.0).

    Example:

    /// Foo function
    ///
    /// Does something.
    #[since(version = "1.0.0")]
    fn foo() {}
    

    The above code will be transformed into:

    /// Foo function
    ///
    /// Does something.
    ///
    /// Since: Version(1.0.0)
    fn foo() {}
    
  • Added: b172dc8e Add macro expand!() to expand a template; by 张炎泼; 2024-04-13

    expand!() renders a template with arguments multiple times.

Example:
```rust,ignore
expand!(KEYED, // ignore duplicate by `K`
        (K, T, V) => {let K: T = V;},
        (a, u64, 1),
        (a, u32, 2), // duplicate `a` will be ignored
        (c, Vec<u8>, vec![1,2])
);
```

The above code will be transformed into:

```rust,ignore
let a: u64 = 1;
let c: Vec<u8> = vec![1, 2];
```
Improved:
  • Improved: 99596c75 declare_raft_types allows the types in any order; by 张炎泼; 2024-04-13

    By rewriting the template expanding part with a #[proc_macro]
    expand!() defined in openraft_macros, declare_raft_types
    does not require the types in fixed order:

    Example:

    declare_raft_types!(All:
            D = (),
            NodeId = u64,
            R = (),
            Node = (),
    
Fixed:
  • Fixed: 14d42e4f Load mebmership since last_applied, not last_membership.index on startup; by 张炎泼; 2024-04-25

    Modify StorageHelper::last_membership_in_log() to scan the log
    starting from the last applied index rather than the index of the last
    applied membership log. This change reduces unnecessary I/O operations
    during startup, previously caused by scanning from an incorrect starting
    point.

v0.9.5

Compare Source

Summary:

  • Added:
    • e4fed706 Add Raft::is_initialized().
    • 3b18517a Add RaftTypeConfig::Responder to customize returning client write response.
    • c508a354 Raft::client_write_ff() ff for fire-and-forget.

Detail:

Added:
  • Added: e4fed706 Add Raft::is_initialized(); by 张炎泼; 2024-04-08

    Raft::is_initialized() returns true if this raft node is already
    initialized with Raft::initialize(), by checking if log is empty and
    vote is not written.

  • Added: 3b18517a Add RaftTypeConfig::Responder to customize returning client write response; by 张炎泼; 2024-04-03

    This commit introduces the Responder trait that defines the mechanism
    by which RaftCore sends responses back to the client after processing
    write requests. Applications can now customize response handling by
    implementing their own version of the RaftTypeConfig::Responder trait.

    The Responder::from_app_data(RaftTypeConfig::D) method is invoked to
    create a new Responder instance when a client write request is
    received.
    Once the write operation is completed within RaftCore,
    Responder::send(WriteResult) is called to dispatch the result
    back to the client.

    By default, RaftTypeConfig::Responder retains the existing
    functionality using a oneshot channel, ensuring backward compatibility.

    This change is non-breaking, requiring no modifications to existing
    applications.

  • Added: c508a354 Raft::client_write_ff() ff for fire-and-forget; by 张炎泼; 2024-04-08

    Raft<C>::client_write_ff() -> C::Responder::Receiver submit a client
    request to Raft to update the state machine, returns an application
    defined response receiver Responder::Receiver to receive the response.

    _ff means fire and forget.

    It is same as [Raft::client_write] but does not wait for the response.
    When using this method, it is the application's responsibility for
    defining mechanism building and consuming the Responder::Receiver.

Full Changelog: https://github.com/datafuselabs/openraft/compare/v0.9.4...v0.9.5

v0.9.4

Compare Source

Summary:

  • Changed:
    • 2b8bc842 Add default value to declare_raft_types.
  • Added:
    • 93c0d9ae Implement TryAsRef<ForwardToLeader<..>> for RaftError.

Detail:

Changed:
  • Changed: 2b8bc842 Add default value to declare_raft_types;

    Types used in declare_raft_types can be omitted, in which case the default type will be used.
    The default values for each type are:

    • D: String
    • R: String
    • NodeId: u64
    • Node: ::openraft::BasicNode
    • Entry: ::openraft::Entry<Self>
    • SnapshotData: Cursor<Vec<u8>>
    • AsyncRuntime: ::openraft::TokioRuntime

    Note that The types must be specified in the exact order:
    D, R, NodeId, Node, Entry, SnapshotData, AsyncRuntime.

    For example, to declare with only D, R and Entry types:

    openraft::declare_raft_types!(
       pub TypeConfig:
           D = ClientRequest,
           R = ClientResponse,
           Entry = MyEntry,
    );
    

    Type NodeId, Node, SnapshotData and AsyncRuntime will be filled
    with default values mentioned above.

    Or one can just use the default types for all:

    openraft::declare_raft_types!(pub TypeConfig);
    

    Upgrade tip:

    Ensures types declared in declare_raft_types are in the correct order

Added:
  • Added: 93c0d9ae Implement TryAsRef<ForwardToLeader<..>> for RaftError;

Full Changelog: https://github.com/datafuselabs/openraft/compare/v0.9.3...v0.9.4

Contributors

v0.9.3

Compare Source

v0.9.2

Compare Source

  • Added:
    • 8b54a80f Raft::config() returns a ref to Config this raft node uses.
    • 7d5326ce add RaftMetrics::millis_since_quorum_ack.
  • Improved:
    • d4a3053f Update example network err implementation.
    • d2d155db Use Unreachable error in examples/raft-kv-rocksdb.
  • Fixed:
    • 17795e7f Ensure heartbeat results are returned to RaftCore.
    • 768dfdc9 Ensure RaftMetrics are sent after RaftDataMetrics and RaftServerMetrics.

v0.9.1

Compare Source

v0.9.0

Compare Source

Summary:

  • Changed:
    • 6098f5cf add AsyncRuntime type parameter to RaftTypeConfig (#​869).
    • 4c488a61 move external command trigger to dedicated Trigger struct (#​888).
    • 5d37d4c3 move runtime config API to dedicated RuntimeConfigHandle.
    • 8a81df53 RaftLogReaderExt::get_log_id() should not return last-purged-id.
    • 330b1fff move get_log_state() from RaftLogReader to RaftStorage.
    • 87c0d74f remove N, LS, SM from Raft<C, N, LS, SM>.
    • 22cd3bb4 remove deprecated RaftNetwork methods without option argument.
    • a1c7f6e6 remove openraft-0.7 compatibility support.
  • Added:
    • d629dbeb add ChangeMembers::SetNodes (#​876).
    • 104983db add 'singlethreaded' raft mode (#​878).
    • 942ec78b save committed log id.
    • 6d42c6e2 permit follower log to revert to earlier state with --features loosen-follower-log-revert.
    • 3fc8ede6 add feature flag "tracing-log" to emit log record for tracing event.
    • 961469c0 add PayloadTooLarge error.
    • ee3b9421 add Raft::with_raft_state() to access RaftState with a function.
    • d1607529 Add new methods to openraft::metrics::Wait.
    • 79372b4d add Raft::ensure_linearizable() to ensure linearizable read.
    • 82615896 add Raft::data_metrics() and Raft::server_metrics() (#​990).
    • c1cf8a82 add Raft::get_snapshot() to get the last snapshot from state machine.
    • c1aa1b5a add Raft::install_full_snapshot() to install a snapshot.
    • 5631ecfb Add Raft::begin_receiving_snapshot().
    • 687fcf2f RaftNetwork::full_snapshot() to send a complete snapshot.
    • 907f5f74 feature flag generic-snapshot-data.
    • 884f0da6 add trait RaftLogStorageExt to provide additional raft-log methods.
  • Fixed:
    • 86b46a08 restore replication progress when a leader starts up (#​884).
    • 97254a31 Do not report snapshot.last_log_id to metrics until snapshot is finished building/installing.
    • ffae5224 AsyncReadExt::read_buf() only reads at most 2MB per call.
    • f41729a1 End tick_loop() when the receiver is gone.
    • 0799972e Split serde bound for RaftError into serialize and deserialize.
  • Improved:
    • 06b431bf replace async_trait with RPITIT.

Detail:

Changed:
  • Changed: 6098f5cf add AsyncRuntime type parameter to RaftTypeConfig (#​869); by wvwwvwwv; 2023-06-21

    • Add AsyncRuntime type parameter to RaftTypeConfig

      This commit introduces the AsyncRuntime type parameter to
      RaftTypeConfig, allowing applications to choose their preferred
      asynchronous runtime, such as tokio or async-std.

    • Parameterize Instant type for flexibility with async runtimes

      To create a more flexible interface between the crate and
      asynchronous runtimes, the Instant type is now associated with the
      async runtime. This is because Instant::now can have different
      implementations. This commit adds the trait Instant and TokioInstant
      for representing system states.

    • Fix: #​741

  • Changed: 4c488a61 move external command trigger to dedicated Trigger struct (#​888); by 张炎泼; 2023-07-01

    • Refactor: move RaftTypeConfig to separate file

    • Change: move external command trigger to dedicated Trigger struct

    Moved trigger election, heartbeat, snapshot and purge log from Raft
    to a new Trigger struct, to separate externally trigger actions from
    the main Raft API.


    Marked the old trigger methods in Raft as deprecated, and recommended
    using the new Trigger struct instead.

    The main motivation of these changes is to organize the Raft API in a
    more structured way, by extracting trigger actions into a dedicated
    struct, instead of mixing them together in the Raft API.

  • Changed: 5d37d4c3 move runtime config API to dedicated RuntimeConfigHandle; by 张炎泼; 2023-07-02

  • Changed: 8a81df53 RaftLogReaderExt::get_log_id() should not return last-purged-id; by 张炎泼; 2023-07-02

    get_log_id() should only return present log id,
    and should not be responsible to return id of an already purged log
    entry, which introduce unnecessary complexity.

    Upgrade tip:

    An RaftStorage implementation should have already maintained the
    last-purge-log-id. Avoid getting it via RaftLogReaderExt::get_log_id().

  • Changed: 330b1fff move get_log_state() from RaftLogReader to RaftStorage; by 张炎泼; 2023-07-03

    • Move the get_log_state() method from the RaftLogReader trait to
      the RaftStorage trait.

    • For applications that enable the storage-v2 feature,
      get_log_state() will be moved from RaftLogReader to
      RaftLogStorage.

    • get_log_state() should only be called once when openraft starts up.
      Only the ReplicationCore uses RaftLogReader, and it does not need
      get_log_state(). The log entries to replicate are decided by
      RaftCore.

    Upgrade tip:

    Implement get_log_state() in the RaftStorage or RaftLogStorage
    trait instead of RaftLogReader.

    Refer to the changes in rocksstore/src/lib.rs in this commit for an
    example.

  • Changed: 87c0d74f remove N, LS, SM from Raft<C, N, LS, SM>; by 张炎泼; 2023-11-20

    • Raft<C, ..>: is a control handle of RaftCore and it does not directly
      rely on N: RaftNetworkFactory, LS: RaftLogStorage and
      SM: RaftStateMachine.
      Thus these types should not be part of Raft.

      In this commit, we remove N, LS, SM from Raft<C, N, LS, SM>,
      RaftInner<C, N, LS> and RaftMsg<C, N, LS>.
      Type N, LS, SM now are only used by Raft::new() which needs these
      types to create RaftCore.

    • Raft::external_request(): Another change is the signature of the
      Fn passed to Raft::external_request() changes from
      FnOnce(&RaftState, &mut LS, &mut N) to FnOnce(&RaftState).

    • Fix: the FnOnce passed to Raft::external_request() should always
      be Send, unoptionally. Because it is used to send from Raft to
      RaftCore.

    • Fix: #​939

  • Changed: 22cd3bb4 remove deprecated RaftNetwork methods without option argument; by 张炎泼; 2024-02-24

  • Changed: a1c7f6e6 remove openraft-0.7 compatibility support; by 张炎泼; 2024-03-04

Added:
  • Added: d629dbeb add ChangeMembers::SetNodes (#​876); by 张炎泼; 2023-06-22

    During dynamic cluster changes, we sometimes need to update an existing
    node, for example changing its network address.

    Adding SetNodes variant to ChangeMembers allows replacing an
    existing node directly.
    However, this also carries risk of creating a split brain scenario if
    used incorrectly.

  • Added: 104983db add 'singlethreaded' raft mode (#​878); by wvwwvwwv; 2023-06-27

    • Feature: add 'singlethreaded' raft mode
    • 'singlethreaded' compile-time feature gate.

    The new feature gate forces the raft instance to be used by a single thread by not implementing Send for certain data structures and substituting calls to tokio::spawn with tokio::spawn_local when using the tokio asynchronous runtime.

    • Re-export add_async_trait for application to define a !Send async trait.

    • Fix: #​862

  • Added: 942ec78b save committed log id; by 张炎泼; 2023-07-16

    • Wrote committed log id to storage
      Save the committed log id to storage before Raft apply log entries. This can
      recover state machine to the state corresponding to the committed log id upon
      system startup.

    • Re-applied log entries after startup
      If the last applied log id is smaller than the committed log id saved in
      storage, re-apply log entries from the next index of last applied log id to the
      committed log id.

    Version 1 storage API RaftStorage and Version 2 storage API
    RaftLogStorage both add API save_committed() and read_committed()
    to support saving/reading committed log id.

    These two new API are optional and provides default dummy
    implementation, an application does not need any modifications if it
    does not need this feature.

  • Added: 6d42c6e2 permit follower log to revert to earlier state with --features loosen-follower-log-revert; by 张炎泼; 2023-07-20

    Add a new feature flag loosen-follower-log-revert, to permit the
    follower's log to roll back to an earlier state without causing the
    leader to panic.

    Although log state reversion is typically seen as a bug, enabling it can
    be useful for testing or in some special scenarios.
    For instance, in an even number nodes cluster, erasing a node's data
    and then rebooting it(log reverts to empty) will not result in data
    loss.

  • Added: 3fc8ede6 add feature flag "tracing-log" to emit log record for tracing event; by 张炎泼; 2023-08-02

  • Added: 961469c0 add PayloadTooLarge error; by 张炎泼; 2023-11-24

    If a RaftNetwork implmentation found an AppendEntriesRequest is too
    large, it could return a PayloadTooLarge::new_entries_hint(n) error to
    tell openraft devide request into smaller chunks containing at most n
    entries. Openraft will limit the number of entries in the next 10
    AppendEntrie RPC.

    Exmaple:

    impl<C: RaftTypeConfig> RaftNetwork<C> for MyNetwork {
        fn append_entries(&self,
                rpc: AppendEntriesRequest<C>,
                option: RPCOption
        ) -> Result<_, RPCError<C::NodeId, C::Node, RaftError<C::NodeId>>> {
            if rpc.entries.len() > 10 {
                return Err(PayloadTooLarge::new_entries_hint(10).into());
            }
            // ...
        }
    }
    
  • Added: ee3b9421 add Raft::with_raft_state() to access RaftState with a function; by 张炎泼; 2023-12-06

    This new method serves as a convenience wrapper around
    Raft::external_request(), streamlining use cases where only a single
    value needs to be returned.

    Thanks to @​tvsfx

  • Added: d1607529 Add new methods to openraft::metrics::Wait; by 张炎泼; 2023-12-07

    Add log_index(), log_index_at_least(), applied_index() and
    applied_index_at_least() to openraft::metrics::Wait to replace
    Wait::log() and Wait::log_at_least().

    These two methods are deprecated since 0.9.0 because the names does
    not imply that they will be blocked by last_applied log index.

    Thanks to @​tvsfx

  • Added: 79372b4d add Raft::ensure_linearizable() to ensure linearizable read; by 张炎泼; 2023-12-07

    The Raft::is_leader() method does not fully ensure linearizable read
    operations and is deprecated in this version. Instead, applications
    should use the Raft::ensure_linearizable() method to guarantee
    linearizability.

    Under the hood, Raft::ensure_linearizable() obtains a ReadIndex from
    RaftCore if it remains the leader, and blocks until the state
    machine applies up to the ReadIndex. This process ensures that the
    application observes all state visible to a preceding read operation.

    Upgrade tip:

    Replace Raft::is_leader() with Raft::ensure_linearizable().

  • Added: 82615896 add Raft::data_metrics() and Raft::server_metrics() (#​990); by YangKian; 2024-01-14

  • Added: c1cf8a82 add Raft::get_snapshot() to get the last snapshot from state machine; by 张炎泼; 2024-02-10

  • Added: c1aa1b5a add Raft::install_full_snapshot() to install a snapshot; by 张炎泼; 2024-02-10

    Using this method, the application provides a full snapshot to
    Openraft, which is then used to install and replace the state machine.
    It is entirely the responsibility of the application to acquire a
    snapshot through any means: be it in chunks, as a stream, or via shared
    storage solutions like S3.

    This method necessitates that the caller supplies a valid Vote to
    confirm the legitimacy of the leader, mirroring the requirements of
    other Raft protocol APIs such as append_entries and vote.

  • Added: 5631ecfb Add Raft::begin_receiving_snapshot(); by 张炎泼; 2024-02-14

    Raft::begin_receiving_snapshot() request the state machine to return a
    SnapshotData for receiving snapshot from the leader.
    Internally it calls RaftStateMachine::begin_receiving_snapshot()

    Handling snapshot receiving is moved out of state-machine worker task.
    Now it is in implemented outside the RaftCore.
    Receiving snapshot could be totally application specific and should not
    be part of Openraft.

    The in sm-worker snapshot receiving is removed.

  • Added: 687fcf2f RaftNetwork::full_snapshot() to send a complete snapshot; by 张炎泼; 2024-02-11

    Add RaftNetwork::snapshot() to send a complete snapshot and move
    sending snapshot by chunks out of ReplicationCore.

    To enable a fully customizable implementation of snapshot transmission
    tailored to the application's needs, this commit relocates the
    chunk-by-chunk transmission logic from ReplicationCore to a new
    sub mod, crate::network::snapshot_transport.

    The snapshot_transport mod provides a default chunk-based snapshot
    transmission mechanism, which can be overridden by creating a custom
    implementation of the RaftNetwork::full_snapshot() method. As part of this
    commit, RaftNetwork::full_snapshot() simply delegates to snapshot_transport.
    Developers may use snapshot_transport as a reference when implementing
    their own snapshot transmission strategy.

    Snapshot transmission is internally divided into two distinct phases:

    1. Upon request for snapshot transmission, ReplicationCore initiates a
      new task RaftNetwork::full_snapshot() dedicated to sending a complete
      Snapshot. This task should be able to be terminated gracefully by
      subscribing the cancel future.

    2. Once the snapshot has been fully transmitted by
      RaftNetwork::full_snapshot(), the task signals an event back to
      ReplicationCore. Subsequently, ReplicationCore informs RaftCore
      of the event, allowing it to acknowledge the completion of the
      snapshot transmission.

    Other changes:

    • ReplicationCore has two RaftNetworks, one for log replication and
      heartbeat, the other for snapshot only.

    • ReplicationClosed becomes a public error for notifying the
      application implemented sender that a snapshot replication is
      canceled.

    • StreamingError is introduced as a container of errors that may occur
      in application defined snapshot transmission, including local IO
      error, network errors, errors returned by remote peer and ReplicationClosed.

    • The SnapshotResponse type is introduced to differentiate it from the
      InstallSnapshotResponse, which is used for chunk-based responses.

  • Added: 907f5f74 feature flag generic-snapshot-data; by 张炎泼; 2024-02-16

    Add feature flag generic-snapshot-data: when enabled, SnapshotData
    does not have AsyncSeek + AsyncRead + AsyncWrite bound.
    This enables application to define their own snapshot format and
    transmission protocol.

    If this feature flag is not eabled, no changes are required for
    application to upgrade Openraft.

    On the sending end(leader that sends snapshot to follower):

    • Without generic-snapshot-data: RaftNetwork::snapshot()
      provides a default implementation that invokes the chunk based API
      RaftNetwork::install_snapshot() for transmit.

    • With generic-snapshot-data enabled: RaftNetwork::snapshot() must be
      implemented to provide application customized snapshot transmission.
      Application does not need to implement RaftNetwork::install_snapshot().

    On the receiving end(follower):

    • Raft::install_snapshot() is available only when
      generic-snapshot-data is disabled.

    Add an example examples/raft-kv-memstore-generic-snapshot-data with
    generic-snapshot-data enabled.
    In this example snapshot is transmitted without fragmentation, i.e., via
    RaftNetwork::snapshot(). The chunk based API
    RaftNetwork::install_snapshot() is not used.
    In a production scenario, a snapshot can be transmitted in arbitrary
    manner.

  • Added: 884f0da6 add trait RaftLogStorageExt to provide additional raft-log methods; by 张炎泼; 2024-03-04

    The RaftLogReaderExt::blocking_append() method enables the caller to
    append logs to storage in a blocking manner, eliminating the need to
    create and await a callback. This method simplifies the process of
    writing tests.

Fixed:
  • Fixed: 86b46a08 restore replication progress when a leader starts up (#​884); by 张炎泼; 2023-06-29

    As a leader, the replication progress to itself should be restored upon
    startup.

    And if this leader is the only node in a cluster, it should re-apply all
    of the logs to state machine at once.

  • Fixed: 97254a31 Do not report snapshot.last_log_id to metrics until snapshot is finished building/installing; by 张炎泼; 2023-10-18

    Before this commit RaftMetrics.snapshot contains the last log id of a
    snapshot that is going to install. Therefore there is chance the
    metrics is updated but the store does not.

    In this commit, RaftMetrics.snapshot will only be updated when a
    snapshot is finished building or installing, by adding a new field
    snpashot to IOState for tracking persisted snapshot meta data.

  • Fixed: ffae5224 AsyncReadExt::read_buf() only reads at most 2MB per call; by 张炎泼; 2023-11-08

    When streaming a snapshot chunk, it should repeatly read_buf() until
    snapshot_max_chunk_size is full or read EOF.

  • Fixed: f41729a1 End tick_loop() when the receiver is gone.; by Ivan Schréter; 2023-11-13

    Currently, tick_loop() would keep printing the trace message every
    tick even when the receiver (Raft main loop) is gone in this form:

    INFO openraft::core::tick: .../tick.rs:70: Tick fails to send, receiving end quit: channel closed

    If the tick message fails to send, then terminate the loop, since every
    future message will fail to send as well.

    Also adjust the trace message to better describe what happened.

  • Fixed: 0799972e Split serde bound for RaftError into serialize and deserialize; by Thomas Van Strydonck; 2024-01-16

Improved:
  • Improved: 06b431bf replace async_trait with RPITIT; by Josh Griffith; 2024-01-28

v0.8.9

Compare Source

What's Changed

New Contributors

Full Changelog: https://github.com/datafuselabs/openraft/compare/v0.8.3...v0.8.9


Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [openraft](https://github.com/datafuselabs/openraft) | dependencies | minor | `0.8.8` -> `0.9.0` | --- ### Release Notes <details> <summary>datafuselabs/openraft (openraft)</summary> ### [`v0.9.17`](https://github.com/databendlabs/openraft/releases/tag/v0.9.17) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.16...v0.9.17) Summary: - Improved: - [536a435e](https://github.com/datafuselabs/openraft/commit/536a435e2fccc98c37a776322d0f7e4aba26c179) Chunk read log entry and check range on startup. - [dc18dc6f](https://github.com/datafuselabs/openraft/commit/dc18dc6f5fed49c1a4717133fbc489eb57efda79) remove `Copy` bound from `NodeId`. Detail: ##### Improved: - Improved: [536a435e](https://github.com/datafuselabs/openraft/commit/536a435e2fccc98c37a776322d0f7e4aba26c179) Chunk read log entry and check range on startup; by 张炎泼; 2024-09-14 - Implement chunk-based reading of committed log entries when re-applying to state machine upon startup. - Add validation for log entry indexes, to avoid applying wrong entries to state machine. - Improved: [dc18dc6f](https://github.com/datafuselabs/openraft/commit/dc18dc6f5fed49c1a4717133fbc489eb57efda79) remove `Copy` bound from `NodeId`; by 张炎泼; 2024-10-14 The `NodeId` type is currently defined as: ```rust type NodeId: .. + Copy + .. + 'static; ``` This commit removes the `Copy` bound from `NodeId`. This modification will allow the use of non-`Copy` types as `NodeId`, providing greater flexibility for applications that prefer variable-length strings or other non-`Copy` types for node identification. This change maintain compatibility by updating derived `Copy` implementations with manual implementations: ```rust // Before #[derive(Copy...)] pub struct LogId<NID: NodeId> {} // After impl<NID: Copy> Copy for LogId<NID> {} ``` ### [`v0.9.16`](https://github.com/databendlabs/openraft/releases/tag/v0.9.16) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.15...v0.9.16) #### What's Changed - Fix: Prevent panic when calling `Raft::change_membership()` on uninitialized node by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/1243 **Full Changelog**: https://github.com/datafuselabs/openraft/compare/v0.9.15...v0.9.16 ### [`v0.9.15`](https://github.com/databendlabs/openraft/releases/tag/v0.9.15) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.14...v0.9.15) Summary: - Fixed: - [0b1293f3](https://github.com/datafuselabs/openraft/commit/0b1293f3499de8d2e3dfb7b0d06f37e08c8ac759) Should not update `vote` when seeing higher vote in `RequestVote` response. - [94b1e843](https://github.com/datafuselabs/openraft/commit/94b1e84374e52bdc2e317d7abf5cfa9fb1970254) Clarify that receiving an equal vote does not grant leadership. - Added: - [5f5d7e9f](https://github.com/datafuselabs/openraft/commit/5f5d7e9f60ff2e86af078d2c20401636de2c19f7) Add `TypeConfigExt` to simplify `RaftTypeConfig` Access. Detail: ##### Fixed: - Fixed: [0b1293f3](https://github.com/datafuselabs/openraft/commit/0b1293f3499de8d2e3dfb7b0d06f37e08c8ac759) Should not update `vote` when seeing higher vote in `RequestVote` response; by 张炎泼; 2024-07-04 This commit addresses an issue in the vote updating mechanism during the handling of `RequestVote` responses. Previously, encountering a higher `vote` in a response incorrectly led to an update of the local `state.vote`, which could break Raft consistency rules. **Issue Description:** - A higher `vote` seen in a `RequestVote` response does not necessarily mean that the vote is granted. The local `state.vote` should only be updated if the vote is actually granted, i.e., the responding node has a higher `vote` and a `last_log_id` that allows it to become a leader. **Resolution:** - The local `state.vote` will no longer be updated upon merely seeing a higher `vote` in the `RequestVote` response. Instead, this higher vote will be recorded in `last_seen_vote` for consideration in the next election cycle, without updating the current `state.vote`. This bug is introduced in: [`f0a9e34`](https://github.com/datafuselabs/openraft/commit/f0a9e34b12bc937170803dc60a4e2c12de9212ef) - Fixed: [94b1e843](https://github.com/datafuselabs/openraft/commit/94b1e84374e52bdc2e317d7abf5cfa9fb1970254) Clarify that receiving an equal vote does not grant leadership.; by 张炎泼; 2024-08-28 A node's `vote` may be updated when a leader observes a higher vote. In such cases, the leader updates its local vote and steps down. However, this vote update does not imply that the node accepts the higher vote as valid for leadership, as it has not yet compared their logs. In this commit, re-enable `VoteResponse.vote_granted` to indicate a vote is granted. This commit also fix: - Fix: [#&#8203;1236](https://github.com/datafuselabs/openraft/issues/1236) ##### Added: - Added: [5f5d7e9f](https://github.com/datafuselabs/openraft/commit/5f5d7e9f60ff2e86af078d2c20401636de2c19f7) Add `TypeConfigExt` to simplify `RaftTypeConfig` Access; by 张炎泼; 2024-07-03 This commit introduces a new trait, `TypeConfigExt`, which extends `RaftTypeConfig`. The purpose of this trait is to simplify the access to various functionalities provided by the `RaftTypeConfig` trait, enhancing code readability and reducing complexity. **Methods Added to `TypeConfigExt`:** - `now()` - `sleep()` - `sleep_until()` - `timeout()` - `timeout_at()` - `oneshot()` - `spawn()` **Usage Improvement:** - Instead of using the `<<C as RaftTypeConfig>::AsyncRuntime as AsyncRuntime>::Instant::now()`, you can now simply call `C::now()`. ### [`v0.9.14`](https://github.com/datafuselabs/openraft/compare/v0.9.13...v0.9.14) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.13...v0.9.14) ### [`v0.9.13`](https://github.com/databendlabs/openraft/releases/tag/v0.9.13) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.12...v0.9.13) Summary: - Added: - [fb49efb3](https://github.com/datafuselabs/openraft/commit/fb49efb37e209ab0cd9ea7c4bc243f18f4e9a658) Add `DecomposeResult` to simplify error handling. Detail: ##### Added: - Added: [fb49efb3](https://github.com/datafuselabs/openraft/commit/fb49efb37e209ab0cd9ea7c4bc243f18f4e9a658) Add `DecomposeResult` to simplify error handling; by 张炎泼; 2024-06-20 This commit treats remote errors occurring during RPC, like a `Fatal` error, as an `Unreachable` error. This is due to Openraft's current inability to distinguish between an unreachable node and a broken node. - **Helper trait `DecomposeResult`:** Introduced to simplify handling composite errors. It converts a result of the form `Result<R, ErrorAOrB>` into a nested result `Result<Result<R, ErrorA>, ErrorB>`. ### [`v0.9.12`](https://github.com/databendlabs/openraft/releases/tag/v0.9.12) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.11...v0.9.12) Summary: - DocFixed: - [1385394c](https://github.com/datafuselabs/openraft/commit/1385394c49baecf124ae9aa583753b51b29b443c) RemoveNodes -> add_leaner in dynamic-membership. - Added: - [8cd00388](https://github.com/datafuselabs/openraft/commit/8cd003889ce3f6948187c0f51393ed51e305e794) Add `RaftLogReader::limited_get_log_entries()`. Detail: ##### DocFixed: - DocFixed: [1385394c](https://github.com/datafuselabs/openraft/commit/1385394c49baecf124ae9aa583753b51b29b443c) RemoveNodes -> add_leaner in dynamic-membership; by shuo; 2024-06-08 ##### Added: - Added: [8cd00388](https://github.com/datafuselabs/openraft/commit/8cd003889ce3f6948187c0f51393ed51e305e794) Add `RaftLogReader::limited_get_log_entries()`; by 张炎泼; 2024-06-16 This commit adds the `RaftLogReader::limited_get_log_entries()` method, which enables applications to fetch log entries that are equal to or smaller than a specified range. This functionality is particularly useful for customizing the size of AppendEntries requests at the storage API level. - Applications can now decide the number of log entries to return based on the input range. If the application determines that the requested log entries range is too large for a single RPC, it can opt to return only the first several requested log entries instead of the full range. - The method provides a default implementation that delegates the operation to `RaftLogReader::try_get_log_entries`. This enhancement allows for more flexible and efficient handling of log entries, particularly in scenarios where network constraints or performance considerations require smaller data transfers. ### [`v0.9.11`](https://github.com/databendlabs/openraft/releases/tag/v0.9.11) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.10...v0.9.11) Summary: - Fixed: - [30cdf5fb](https://github.com/datafuselabs/openraft/commit/30cdf5fbc9275ce6213ca8f70cf37bc0c6fe957a) New leader must flush blank log. Detail: ##### Fixed: - Fixed: [30cdf5fb](https://github.com/datafuselabs/openraft/commit/30cdf5fbc9275ce6213ca8f70cf37bc0c6fe957a) New leader must flush blank log; by 张炎泼; 2024-05-14 This commit addresses a critical issue where if a new leader does not flush the blank log to disk upon becoming established and then restarts immediately, there is a possibility that previously committed data becomes invisible to readers. Before the blank log is flushed, the leader (identified by vote `v3`) assumes it will be flushed and commits this log once (|quorum|-1) replication responses are received. If the blank log is lost and the server is restarted, data committed by a new leader (vote `v2`) may not be visible. This issue is addressed by utilizing `LeaderHandler::leader_append_entries()` instead of `ReplicationHandler::append_blank_log()`, where the former does not wait for the blank log to flush. Changes: - When assigning log IDs to log entries, the `Leading.last_log_id`, which represents the state of the log proposer (equivalent term in Paxos is Proposer), should be used instead of `RaftState.last_log_id`, which represents the state of the log receiver (equivalent term in Paxos is Acceptor). - Consequently, the method `assign_log_ids()` has been moved from `RaftState` to `Leading`. - Avoid manual implementation of duplicated logic: - During `initialize()`, reuse `FollowingHandler::do_append_entries()` to submit the very first log to storage. - In `establish_leader()`, reuse `LeaderHandler::leader_append_entries()` to submit log to storage and remove `ReplicationHandler::append_blank_log()`. - Remove `Command::AppendEntry`. ### [`v0.9.10`](https://github.com/databendlabs/openraft/releases/tag/v0.9.10) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.9...v0.9.10) Summary: - Improved: - [14f174e9](https://github.com/datafuselabs/openraft/commit/14f174e9ef422e15485354a4e4ed0f75cc35be26) `cancel` passed to `full_snapshot()` should be `static`. Detail: ##### Improved: - Improved: [14f174e9](https://github.com/datafuselabs/openraft/commit/14f174e9ef422e15485354a4e4ed0f75cc35be26) `cancel` passed to `full_snapshot()` should be `static`; by 张炎泼; 2024-05-06 ### [`v0.9.9`](https://github.com/databendlabs/openraft/releases/tag/v0.9.9) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.8...v0.9.9) Summary: - Fixed: - [8b62c797](https://github.com/datafuselabs/openraft/commit/8b62c797b343df5f496dc1b7c0264d09229e3b4a) Immediate response when snapshot installation is unnecessary. Detail: ##### Fixed: - Fixed: [8b62c797](https://github.com/datafuselabs/openraft/commit/8b62c797b343df5f496dc1b7c0264d09229e3b4a) Immediate response when snapshot installation is unnecessary; by 张炎泼; 2024-05-05 When `Engine::handle_install_full_snapshot()` is called and the provided snapshot is not up-to-date, the snapshot should not be installed, and the response should be sent back immediately. Previously, the method might delay the response unnecessarily, waiting for an installation process that would not proceed. This commit adjusts the logic so that if the snapshot is recognized as outdated, it immediately returns a `None` `Condition`, ensuring the caller is informed straightaway that no installation will occur. ### [`v0.9.8`](https://github.com/databendlabs/openraft/releases/tag/v0.9.8) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.7...v0.9.8) Summary: - Fixed: - [fd5c657f](https://github.com/datafuselabs/openraft/commit/fd5c657f2d08844b7917e599badb4d75875a9611) `Chunked` should reset offset 0 when a `SnapshotMismatch` error is received. Detail: ##### Fixed: - Fixed: [fd5c657f](https://github.com/datafuselabs/openraft/commit/fd5c657f2d08844b7917e599badb4d75875a9611) `Chunked` should reset offset 0 when a `SnapshotMismatch` error is received; by 张炎泼; 2024-05-02 When a `SnapshotMismatch` is received, the sending end should re-send all snapshot data from the beginning. ### [`v0.9.7`](https://github.com/databendlabs/openraft/releases/tag/v0.9.7) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.6...v0.9.7) Summary: - Fixed: - [ff4cf8fe](https://github.com/datafuselabs/openraft/commit/ff4cf8fe4117d8899621619313275d8446ba3e85) openraft-0.9.6 requires openraft-macros-0.9.6 or newer. Detail: ##### Fixed: - Fixed: [ff4cf8fe](https://github.com/datafuselabs/openraft/commit/ff4cf8fe4117d8899621619313275d8446ba3e85) openraft-0.9.6 requires openraft-macros-0.9.6 or newer; by 张炎泼; 2024-04-25 ### [`v0.9.6`](https://github.com/databendlabs/openraft/releases/tag/v0.9.6) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.5...v0.9.6) Summary: - Added: - [5776139d](https://github.com/datafuselabs/openraft/commit/5776139d8ac15d94a800d1e0cf073dea5a7b216e) Add `#[since(version="1.0")]` to specify first version of a feature. - [b172dc8e](https://github.com/datafuselabs/openraft/commit/b172dc8e261f4f2b1149c3ada70524cdf520d5b3) Add macro `expand!()` to expand a template. - Improved: - [99596c75](https://github.com/datafuselabs/openraft/commit/99596c754e19792b97737105acea257d70d1d6b6) `declare_raft_types` allows the types in any order. - Fixed: - [14d42e4f](https://github.com/datafuselabs/openraft/commit/14d42e4f33581dc0ea9c4eeaf0ff00ebec85dbb2) Load mebmership since `last_applied`, not `last_membership.index` on startup. Detail: ##### Added: - Added: [5776139d](https://github.com/datafuselabs/openraft/commit/5776139d8ac15d94a800d1e0cf073dea5a7b216e) Add `#[since(version="1.0")]` to specify first version of a feature; by 张炎泼; 2024-04-12 `#[since(version = "1.0.0")]` adds a doc line `/// Since: Version(1.0.0)`. Example: ```rust,ignore /// Foo function /// /// Does something. #[since(version = "1.0.0")] fn foo() {} ``` The above code will be transformed into: ```rust,ignore /// Foo function /// /// Does something. /// /// Since: Version(1.0.0) fn foo() {} ``` - Added: [b172dc8e](https://github.com/datafuselabs/openraft/commit/b172dc8e261f4f2b1149c3ada70524cdf520d5b3) Add macro `expand!()` to expand a template; by 张炎泼; 2024-04-13 `expand!()` renders a template with arguments multiple times. ##### Example: ```rust,ignore expand!(KEYED, // ignore duplicate by `K` (K, T, V) => {let K: T = V;}, (a, u64, 1), (a, u32, 2), // duplicate `a` will be ignored (c, Vec<u8>, vec![1,2]) ); ``` The above code will be transformed into: ```rust,ignore let a: u64 = 1; let c: Vec<u8> = vec![1, 2]; ``` ##### Improved: - Improved: [99596c75](https://github.com/datafuselabs/openraft/commit/99596c754e19792b97737105acea257d70d1d6b6) `declare_raft_types` allows the types in any order; by 张炎泼; 2024-04-13 By rewriting the template expanding part with a `#[proc_macro]` `expand!()` defined in `openraft_macros`, `declare_raft_types` does not require the types in fixed order: Example: declare_raft_types!(All: D = (), NodeId = u64, R = (), Node = (), ##### Fixed: - Fixed: [14d42e4f](https://github.com/datafuselabs/openraft/commit/14d42e4f33581dc0ea9c4eeaf0ff00ebec85dbb2) Load mebmership since `last_applied`, not `last_membership.index` on startup; by 张炎泼; 2024-04-25 Modify `StorageHelper::last_membership_in_log()` to scan the log starting from the last applied index rather than the index of the last applied membership log. This change reduces unnecessary I/O operations during startup, previously caused by scanning from an incorrect starting point. ### [`v0.9.5`](https://github.com/databendlabs/openraft/releases/tag/v0.9.5) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.4...v0.9.5) Summary: - Added: - [e4fed706](https://github.com/datafuselabs/openraft/commit/e4fed7066ce3f941717285a15de5894c505cb5b1) Add `Raft::is_initialized()`. - [3b18517a](https://github.com/datafuselabs/openraft/commit/3b18517a9a063defc33750faf3fd61d7ebf29c88) Add `RaftTypeConfig::Responder` to customize returning client write response. - [c508a354](https://github.com/datafuselabs/openraft/commit/c508a3540331b5ea08d75b09dfc7a90a87c93b89) `Raft::client_write_ff()` ff for fire-and-forget. Detail: ##### Added: - Added: [e4fed706](https://github.com/datafuselabs/openraft/commit/e4fed7066ce3f941717285a15de5894c505cb5b1) Add `Raft::is_initialized()`; by 张炎泼; 2024-04-08 `Raft::is_initialized()` returns `true` if this raft node is already initialized with `Raft::initialize()`, by checking if log is empty and `vote` is not written. - Added: [3b18517a](https://github.com/datafuselabs/openraft/commit/3b18517a9a063defc33750faf3fd61d7ebf29c88) Add `RaftTypeConfig::Responder` to customize returning client write response; by 张炎泼; 2024-04-03 This commit introduces the `Responder` trait that defines the mechanism by which `RaftCore` sends responses back to the client after processing write requests. Applications can now customize response handling by implementing their own version of the `RaftTypeConfig::Responder` trait. The `Responder::from_app_data(RaftTypeConfig::D)` method is invoked to create a new `Responder` instance when a client write request is received. Once the write operation is completed within `RaftCore`, `Responder::send(WriteResult)` is called to dispatch the result back to the client. By default, `RaftTypeConfig::Responder` retains the existing functionality using a oneshot channel, ensuring backward compatibility. This change is non-breaking, requiring no modifications to existing applications. - Fix: [#&#8203;1068](https://github.com/datafuselabs/openraft/issues/1068) - Added: [c508a354](https://github.com/datafuselabs/openraft/commit/c508a3540331b5ea08d75b09dfc7a90a87c93b89) `Raft::client_write_ff()` ff for fire-and-forget; by 张炎泼; 2024-04-08 `Raft<C>::client_write_ff() -> C::Responder::Receiver` submit a client request to Raft to update the state machine, returns an application defined response receiver `Responder::Receiver` to receive the response. `_ff` means fire and forget. It is same as \[`Raft::client_write`] but does not wait for the response. When using this method, it is the application's responsibility for defining mechanism building and consuming the `Responder::Receiver`. - Part of [#&#8203;1068](https://github.com/datafuselabs/openraft/issues/1068) **Full Changelog**: https://github.com/datafuselabs/openraft/compare/v0.9.4...v0.9.5 ### [`v0.9.4`](https://github.com/databendlabs/openraft/releases/tag/v0.9.4) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.3...v0.9.4) Summary: - Changed: - [2b8bc842](https://github.com/datafuselabs/openraft/commit/2b8bc84277c26e8293cf9d7bc8bcc08b1bd724f3) Add default value to `declare_raft_types`. - Added: - [93c0d9ae](https://github.com/datafuselabs/openraft/commit/93c0d9ae3c0c7574a55be31bf8636936b0721d9b) Implement `TryAsRef<ForwardToLeader<..>>` for `RaftError`. Detail: ##### Changed: - Changed: [2b8bc842](https://github.com/datafuselabs/openraft/commit/2b8bc84277c26e8293cf9d7bc8bcc08b1bd724f3) Add default value to `declare_raft_types`; Types used in `declare_raft_types` can be omitted, in which case the default type will be used. The default values for each type are: - `D`: `String` - `R`: `String` - `NodeId`: `u64` - `Node`: `::openraft::BasicNode` - `Entry`: `::openraft::Entry<Self>` - `SnapshotData`: `Cursor<Vec<u8>>` - `AsyncRuntime`: `::openraft::TokioRuntime` Note that **The types must be specified in the exact order**: `D`, `R`, `NodeId`, `Node`, `Entry`, `SnapshotData`, `AsyncRuntime`. For example, to declare with only `D`, `R` and `Entry` types: ```rust,ignore openraft::declare_raft_types!( pub TypeConfig: D = ClientRequest, R = ClientResponse, Entry = MyEntry, ); ``` Type `NodeId`, `Node`, `SnapshotData` and `AsyncRuntime` will be filled with default values mentioned above. Or one can just use the default types for all: ```rust,ignore openraft::declare_raft_types!(pub TypeConfig); ``` Upgrade tip: Ensures types declared in `declare_raft_types` are in the correct order ##### Added: - Added: [93c0d9ae](https://github.com/datafuselabs/openraft/commit/93c0d9ae3c0c7574a55be31bf8636936b0721d9b) Implement `TryAsRef<ForwardToLeader<..>>` for `RaftError`; **Full Changelog**: https://github.com/datafuselabs/openraft/compare/v0.9.3...v0.9.4 ##### Contributors - [@&#8203;HaHa421](https://github.com/HaHa421) ### [`v0.9.3`](https://github.com/datafuselabs/openraft/compare/v0.9.2...v0.9.3) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.2...v0.9.3) ### [`v0.9.2`](https://github.com/databendlabs/openraft/releases/tag/v0.9.2) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.1...v0.9.2) - Added: - [8b54a80f](https://github.com/datafuselabs/openraft/commit/8b54a80f6e5b06a181f12f55179e0928a470e21b) `Raft::config()` returns a ref to Config this raft node uses. - [7d5326ce](https://github.com/datafuselabs/openraft/commit/7d5326ce7b5534c93300eabbcefa0c4d3d45284e) add `RaftMetrics::millis_since_quorum_ack`. - Improved: - [d4a3053f](https://github.com/datafuselabs/openraft/commit/d4a3053fa7b77fbe7db4fc7e598785b8f4d78676) Update example network err implementation. - [d2d155db](https://github.com/datafuselabs/openraft/commit/d2d155db1e10a619a0bf82710db200ab43afd113) Use `Unreachable` error in `examples/raft-kv-rocksdb`. - Fixed: - [17795e7f](https://github.com/datafuselabs/openraft/commit/17795e7f08bedc3417438aff2486fad261465225) Ensure heartbeat results are returned to `RaftCore`. - [768dfdc9](https://github.com/datafuselabs/openraft/commit/768dfdc9cc1ce5ea1b985dd00274ae8221764ef9) Ensure `RaftMetrics` are sent after `RaftDataMetrics` and `RaftServerMetrics`. ### [`v0.9.1`](https://github.com/datafuselabs/openraft/compare/v0.9.0...v0.9.1) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.9.0...v0.9.1) ### [`v0.9.0`](https://github.com/datafuselabs/openraft/blob/HEAD/change-log.md#v090) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.8.9...v0.9.0) Summary: - Changed: - [6098f5cf](https://github.com/datafuselabs/openraft/commit/6098f5cf61b074c8fccecf722278183c3ee5cd27) add AsyncRuntime type parameter to RaftTypeConfig ([#&#8203;869](https://github.com/datafuselabs/openraft/issues/869)). - [4c488a61](https://github.com/datafuselabs/openraft/commit/4c488a61da8fee614294dea107fdbf0faf15cd28) move external command trigger to dedicated Trigger struct ([#&#8203;888](https://github.com/datafuselabs/openraft/issues/888)). - [5d37d4c3](https://github.com/datafuselabs/openraft/commit/5d37d4c358b0ea6865672934df413dc6bb940c58) move runtime config API to dedicated RuntimeConfigHandle. - [8a81df53](https://github.com/datafuselabs/openraft/commit/8a81df532e45a7dec2e9c6820f654bdc44dccd46) `RaftLogReaderExt::get_log_id()` should not return last-purged-id. - [330b1fff](https://github.com/datafuselabs/openraft/commit/330b1fff7d14fee39f58667db2087de5c3701af1) move `get_log_state()` from RaftLogReader to RaftStorage. - [87c0d74f](https://github.com/datafuselabs/openraft/commit/87c0d74fb4941a87e7aaeb8961e0f9381d637eb9) remove `N, LS, SM` from `Raft<C, N, LS, SM>`. - [22cd3bb4](https://github.com/datafuselabs/openraft/commit/22cd3bb423ddaf21c1f4d70917f689e79a9cacb6) remove deprecated RaftNetwork methods without `option` argument. - [a1c7f6e6](https://github.com/datafuselabs/openraft/commit/a1c7f6e63b3b0b385a2d6289fd406c31cca18834) remove openraft-0.7 compatibility support. - Added: - [d629dbeb](https://github.com/datafuselabs/openraft/commit/d629dbeb65f73e3133e548fe48deb6a645f0dd5a) add `ChangeMembers::SetNodes` ([#&#8203;876](https://github.com/datafuselabs/openraft/issues/876)). - [104983db](https://github.com/datafuselabs/openraft/commit/104983db6bf5a60cd28e0b7237bfd2937a50168a) add 'singlethreaded' raft mode ([#&#8203;878](https://github.com/datafuselabs/openraft/issues/878)). - [942ec78b](https://github.com/datafuselabs/openraft/commit/942ec78bc367665ce82516ad3458e479d895b0ea) save committed log id. - [6d42c6e2](https://github.com/datafuselabs/openraft/commit/6d42c6e24c3bc752ffcaa331df48b5a41eb763b7) permit follower log to revert to earlier state with `--features loosen-follower-log-revert`. - [3fc8ede6](https://github.com/datafuselabs/openraft/commit/3fc8ede609beb787aee8199b06a40ac9742aa116) add feature flag "tracing-log" to emit log record for tracing event. - [961469c0](https://github.com/datafuselabs/openraft/commit/961469c05214059cd536457079b05a10343879e3) add `PayloadTooLarge` error. - [ee3b9421](https://github.com/datafuselabs/openraft/commit/ee3b94216b1964100d6c83a0335072adb589da18) add `Raft::with_raft_state()` to access `RaftState` with a function. - [d1607529](https://github.com/datafuselabs/openraft/commit/d16075293491191c35428350740ad0cd03dd3725) Add new methods to `openraft::metrics::Wait`. - [79372b4d](https://github.com/datafuselabs/openraft/commit/79372b4dff4312f5eb344db76d5ed1dffe69fac7) add `Raft::ensure_linearizable()` to ensure linearizable read. - [82615896](https://github.com/datafuselabs/openraft/commit/82615896eebb85941d20fec85f4cb7ef7798c97d) add `Raft::data_metrics()` and `Raft::server_metrics()` ([#&#8203;990](https://github.com/datafuselabs/openraft/issues/990)). - [c1cf8a82](https://github.com/datafuselabs/openraft/commit/c1cf8a82f15de5bf8d46e5b04823d08698a429f1) add `Raft::get_snapshot()` to get the last snapshot from state machine. - [c1aa1b5a](https://github.com/datafuselabs/openraft/commit/c1aa1b5ab551877ffc40975c4e3d3d376309524b) add `Raft::install_full_snapshot()` to install a snapshot. - [5631ecfb](https://github.com/datafuselabs/openraft/commit/5631ecfb80f51e21ac3f489836000dd256ea6a99) Add `Raft::begin_receiving_snapshot()`. - [687fcf2f](https://github.com/datafuselabs/openraft/commit/687fcf2f7cc0fed878f7a5b9ac96fe63ef793099) `RaftNetwork::full_snapshot()` to send a complete snapshot. - [907f5f74](https://github.com/datafuselabs/openraft/commit/907f5f7494f073a6d1a844cf4ef05d314d76d7a8) feature flag `generic-snapshot-data`. - [884f0da6](https://github.com/datafuselabs/openraft/commit/884f0da65ec10ce5777165e6906c61c326f2394b) add trait `RaftLogStorageExt` to provide additional raft-log methods. - Fixed: - [86b46a08](https://github.com/datafuselabs/openraft/commit/86b46a08090b44511ae481fad8c32ea805ac43d2) restore replication progress when a leader starts up ([#&#8203;884](https://github.com/datafuselabs/openraft/issues/884)). - [97254a31](https://github.com/datafuselabs/openraft/commit/97254a31c673e52429ee7187de96fd2ea2a5ce98) Do not report `snapshot.last_log_id` to metrics until snapshot is finished building/installing. - [ffae5224](https://github.com/datafuselabs/openraft/commit/ffae522425f9a55b1ab4d6ce866d469827932627) `AsyncReadExt::read_buf()` only reads at most 2MB per call. - [f41729a1](https://github.com/datafuselabs/openraft/commit/f41729a18ec147d24a8d00021f619b517aa1bab1) End `tick_loop()` when the receiver is gone. - [0799972e](https://github.com/datafuselabs/openraft/commit/0799972ebeadafbe7a623ed7d74bcda65d342751) Split serde bound for `RaftError` into serialize and deserialize. - Improved: - [06b431bf](https://github.com/datafuselabs/openraft/commit/06b431bf38fbde146e950ad34c4afa1556b48288) replace `async_trait` with RPITIT. Detail: ##### Changed: - Changed: [6098f5cf](https://github.com/datafuselabs/openraft/commit/6098f5cf61b074c8fccecf722278183c3ee5cd27) add AsyncRuntime type parameter to RaftTypeConfig ([#&#8203;869](https://github.com/datafuselabs/openraft/issues/869)); by wvwwvwwv; 2023-06-21 - Add AsyncRuntime type parameter to RaftTypeConfig This commit introduces the AsyncRuntime type parameter to RaftTypeConfig, allowing applications to choose their preferred asynchronous runtime, such as tokio or async-std. - Parameterize Instant type for flexibility with async runtimes To create a more flexible interface between the crate and asynchronous runtimes, the Instant type is now associated with the async runtime. This is because Instant::now can have different implementations. This commit adds the trait Instant and TokioInstant for representing system states. - Fix: [#&#8203;741](https://github.com/datafuselabs/openraft/issues/741) - Changed: [4c488a61](https://github.com/datafuselabs/openraft/commit/4c488a61da8fee614294dea107fdbf0faf15cd28) move external command trigger to dedicated Trigger struct ([#&#8203;888](https://github.com/datafuselabs/openraft/issues/888)); by 张炎泼; 2023-07-01 - Refactor: move RaftTypeConfig to separate file - Change: move external command trigger to dedicated Trigger struct Moved trigger election, heartbeat, snapshot and purge log from `Raft` to a new `Trigger` struct, to separate externally trigger actions from the main Raft API. *** Marked the old trigger methods in `Raft` as deprecated, and recommended using the new `Trigger` struct instead. The main motivation of these changes is to organize the Raft API in a more structured way, by extracting trigger actions into a dedicated struct, instead of mixing them together in the `Raft` API. - Changed: [5d37d4c3](https://github.com/datafuselabs/openraft/commit/5d37d4c358b0ea6865672934df413dc6bb940c58) move runtime config API to dedicated RuntimeConfigHandle; by 张炎泼; 2023-07-02 - Changed: [8a81df53](https://github.com/datafuselabs/openraft/commit/8a81df532e45a7dec2e9c6820f654bdc44dccd46) `RaftLogReaderExt::get_log_id()` should not return last-purged-id; by 张炎泼; 2023-07-02 `get_log_id()` should only return present log id, and should not be responsible to return id of an already purged log entry, which introduce unnecessary complexity. Upgrade tip: An RaftStorage implementation should have already maintained the last-purge-log-id. Avoid getting it via `RaftLogReaderExt::get_log_id()`. - Changed: [330b1fff](https://github.com/datafuselabs/openraft/commit/330b1fff7d14fee39f58667db2087de5c3701af1) move `get_log_state()` from RaftLogReader to RaftStorage; by 张炎泼; 2023-07-03 - Move the `get_log_state()` method from the `RaftLogReader` trait to the `RaftStorage` trait. - For applications that enable the `storage-v2` feature, `get_log_state()` will be moved from `RaftLogReader` to `RaftLogStorage`. - `get_log_state()` should only be called once when openraft starts up. Only the `ReplicationCore` uses `RaftLogReader`, and it does not need `get_log_state()`. The log entries to replicate are decided by `RaftCore`. Upgrade tip: Implement `get_log_state()` in the `RaftStorage` or `RaftLogStorage` trait instead of `RaftLogReader`. Refer to the changes in `rocksstore/src/lib.rs` in this commit for an example. - Changed: [87c0d74f](https://github.com/datafuselabs/openraft/commit/87c0d74fb4941a87e7aaeb8961e0f9381d637eb9) remove `N, LS, SM` from `Raft<C, N, LS, SM>`; by 张炎泼; 2023-11-20 - `Raft<C, ..>`: is a control handle of `RaftCore` and it does not directly rely on `N: RaftNetworkFactory`, `LS: RaftLogStorage` and `SM: RaftStateMachine`. Thus these types should not be part of `Raft`. In this commit, we remove `N, LS, SM` from `Raft<C, N, LS, SM>`, `RaftInner<C, N, LS>` and `RaftMsg<C, N, LS>`. Type `N, LS, SM` now are only used by `Raft::new()` which needs these types to create `RaftCore`. - `Raft::external_request()`: Another change is the signature of the `Fn` passed to `Raft::external_request()` changes from `FnOnce(&RaftState, &mut LS, &mut N)` to `FnOnce(&RaftState)`. - Fix: the `FnOnce` passed to `Raft::external_request()` should always be `Send`, unoptionally. Because it is used to send from `Raft` to `RaftCore`. - Fix: [#&#8203;939](https://github.com/datafuselabs/openraft/issues/939) - Changed: [22cd3bb4](https://github.com/datafuselabs/openraft/commit/22cd3bb423ddaf21c1f4d70917f689e79a9cacb6) remove deprecated RaftNetwork methods without `option` argument; by 张炎泼; 2024-02-24 - Changed: [a1c7f6e6](https://github.com/datafuselabs/openraft/commit/a1c7f6e63b3b0b385a2d6289fd406c31cca18834) remove openraft-0.7 compatibility support; by 张炎泼; 2024-03-04 ##### Added: - Added: [d629dbeb](https://github.com/datafuselabs/openraft/commit/d629dbeb65f73e3133e548fe48deb6a645f0dd5a) add `ChangeMembers::SetNodes` ([#&#8203;876](https://github.com/datafuselabs/openraft/issues/876)); by 张炎泼; 2023-06-22 During dynamic cluster changes, we sometimes need to update an existing node, for example changing its network address. Adding `SetNodes` variant to `ChangeMembers` allows replacing an existing node directly. However, this also carries risk of creating a split brain scenario if used incorrectly. - Fix: [#&#8203;875](https://github.com/datafuselabs/openraft/issues/875) - Added: [104983db](https://github.com/datafuselabs/openraft/commit/104983db6bf5a60cd28e0b7237bfd2937a50168a) add 'singlethreaded' raft mode ([#&#8203;878](https://github.com/datafuselabs/openraft/issues/878)); by wvwwvwwv; 2023-06-27 - Feature: add 'singlethreaded' raft mode <!----> - 'singlethreaded' compile-time feature gate. The new feature gate forces the raft instance to be used by a single thread by not implementing `Send` for certain data structures and substituting calls to `tokio::spawn` with `tokio::spawn_local` when using the `tokio` asynchronous runtime. - Re-export `add_async_trait` for application to define a `!Send` async trait. - Fix: [#&#8203;862](https://github.com/datafuselabs/openraft/issues/862) - Added: [942ec78b](https://github.com/datafuselabs/openraft/commit/942ec78bc367665ce82516ad3458e479d895b0ea) save committed log id; by 张炎泼; 2023-07-16 - **Wrote committed log id to storage** Save the committed log id to storage before Raft apply log entries. This can recover state machine to the state corresponding to the committed log id upon system startup. - **Re-applied log entries after startup** If the last applied log id is smaller than the committed log id saved in storage, re-apply log entries from the next index of last applied log id to the committed log id. Version 1 storage API `RaftStorage` and Version 2 storage API `RaftLogStorage` both add API `save_committed()` and `read_committed()` to support saving/reading committed log id. These two new API are optional and provides default dummy implementation, an application does not need any modifications if it does not need this feature. - Added: [6d42c6e2](https://github.com/datafuselabs/openraft/commit/6d42c6e24c3bc752ffcaa331df48b5a41eb763b7) permit follower log to revert to earlier state with `--features loosen-follower-log-revert`; by 张炎泼; 2023-07-20 Add a new feature flag `loosen-follower-log-revert`, to permit the follower's log to roll back to an earlier state without causing the leader to panic. Although log state reversion is typically seen as a bug, enabling it can be useful for testing or in some special scenarios. For instance, in an even number nodes cluster, erasing a node's data and then rebooting it(log reverts to empty) will not result in data loss. - Related issue: [#&#8203;898](https://github.com/datafuselabs/openraft/issues/898) - Added: [3fc8ede6](https://github.com/datafuselabs/openraft/commit/3fc8ede609beb787aee8199b06a40ac9742aa116) add feature flag "tracing-log" to emit log record for tracing event; by 张炎泼; 2023-08-02 - Added: [961469c0](https://github.com/datafuselabs/openraft/commit/961469c05214059cd536457079b05a10343879e3) add `PayloadTooLarge` error; by 张炎泼; 2023-11-24 If a `RaftNetwork` implmentation found an `AppendEntriesRequest` is too large, it could return a `PayloadTooLarge::new_entries_hint(n)` error to tell openraft devide request into smaller chunks containing at most `n` entries. Openraft will limit the number of entries in the next 10 `AppendEntrie` RPC. Exmaple: ```rust impl<C: RaftTypeConfig> RaftNetwork<C> for MyNetwork { fn append_entries(&self, rpc: AppendEntriesRequest<C>, option: RPCOption ) -> Result<_, RPCError<C::NodeId, C::Node, RaftError<C::NodeId>>> { if rpc.entries.len() > 10 { return Err(PayloadTooLarge::new_entries_hint(10).into()); } // ... } } ``` - Added: [ee3b9421](https://github.com/datafuselabs/openraft/commit/ee3b94216b1964100d6c83a0335072adb589da18) add `Raft::with_raft_state()` to access `RaftState` with a function; by 张炎泼; 2023-12-06 This new method serves as a convenience wrapper around `Raft::external_request()`, streamlining use cases where only a single value needs to be returned. Thanks to [@&#8203;tvsfx](https://github.com/tvsfx) - Added: [d1607529](https://github.com/datafuselabs/openraft/commit/d16075293491191c35428350740ad0cd03dd3725) Add new methods to `openraft::metrics::Wait`; by 张炎泼; 2023-12-07 Add `log_index()`, `log_index_at_least()`, `applied_index()` and `applied_index_at_least()` to `openraft::metrics::Wait` to replace `Wait::log()` and `Wait::log_at_least()`. These two methods are deprecated since `0.9.0` because the names does not imply that they will be blocked by `last_applied` log index. Thanks to [@&#8203;tvsfx](https://github.com/tvsfx) - Added: [79372b4d](https://github.com/datafuselabs/openraft/commit/79372b4dff4312f5eb344db76d5ed1dffe69fac7) add `Raft::ensure_linearizable()` to ensure linearizable read; by 张炎泼; 2023-12-07 The `Raft::is_leader()` method does not fully ensure linearizable read operations and is deprecated in this version. Instead, applications should use the `Raft::ensure_linearizable()` method to guarantee linearizability. Under the hood, `Raft::ensure_linearizable()` obtains a `ReadIndex` from `RaftCore` if it remains the leader, and blocks until the state machine applies up to the `ReadIndex`. This process ensures that the application observes all state visible to a preceding read operation. - Fix: [#&#8203;965](https://github.com/datafuselabs/openraft/issues/965) Upgrade tip: Replace `Raft::is_leader()` with `Raft::ensure_linearizable()`. - Added: [82615896](https://github.com/datafuselabs/openraft/commit/82615896eebb85941d20fec85f4cb7ef7798c97d) add `Raft::data_metrics()` and `Raft::server_metrics()` ([#&#8203;990](https://github.com/datafuselabs/openraft/issues/990)); by YangKian; 2024-01-14 - Added: [c1cf8a82](https://github.com/datafuselabs/openraft/commit/c1cf8a82f15de5bf8d46e5b04823d08698a429f1) add `Raft::get_snapshot()` to get the last snapshot from state machine; by 张炎泼; 2024-02-10 - Added: [c1aa1b5a](https://github.com/datafuselabs/openraft/commit/c1aa1b5ab551877ffc40975c4e3d3d376309524b) add `Raft::install_full_snapshot()` to install a snapshot; by 张炎泼; 2024-02-10 Using this method, the application provides a full snapshot to Openraft, which is then used to install and replace the state machine. It is entirely the responsibility of the application to acquire a snapshot through any means: be it in chunks, as a stream, or via shared storage solutions like S3. This method necessitates that the caller supplies a valid `Vote` to confirm the legitimacy of the leader, mirroring the requirements of other Raft protocol APIs such as `append_entries` and `vote`. - Part of [#&#8203;606](https://github.com/datafuselabs/openraft/issues/606) - Added: [5631ecfb](https://github.com/datafuselabs/openraft/commit/5631ecfb80f51e21ac3f489836000dd256ea6a99) Add `Raft::begin_receiving_snapshot()`; by 张炎泼; 2024-02-14 `Raft::begin_receiving_snapshot()` request the state machine to return a `SnapshotData` for receiving snapshot from the leader. Internally it calls `RaftStateMachine::begin_receiving_snapshot()` Handling snapshot receiving is moved out of state-machine worker task. Now it is in implemented outside the `RaftCore`. Receiving snapshot could be totally application specific and should not be part of Openraft. The in sm-worker snapshot receiving is removed. - Part of [#&#8203;606](https://github.com/datafuselabs/openraft/issues/606) - Added: [687fcf2f](https://github.com/datafuselabs/openraft/commit/687fcf2f7cc0fed878f7a5b9ac96fe63ef793099) `RaftNetwork::full_snapshot()` to send a complete snapshot; by 张炎泼; 2024-02-11 Add `RaftNetwork::snapshot()` to send a complete snapshot and move sending snapshot by chunks out of ReplicationCore. To enable a fully customizable implementation of snapshot transmission tailored to the application's needs, this commit relocates the chunk-by-chunk transmission logic from `ReplicationCore` to a new sub mod, `crate::network::snapshot_transport`. The `snapshot_transport` mod provides a default chunk-based snapshot transmission mechanism, which can be overridden by creating a custom implementation of the `RaftNetwork::full_snapshot()` method. As part of this commit, `RaftNetwork::full_snapshot()` simply delegates to `snapshot_transport`. Developers may use `snapshot_transport` as a reference when implementing their own snapshot transmission strategy. Snapshot transmission is internally divided into two distinct phases: 1. Upon request for snapshot transmission, `ReplicationCore` initiates a new task `RaftNetwork::full_snapshot()` dedicated to sending a complete `Snapshot`. This task should be able to be terminated gracefully by subscribing the `cancel` future. 2. Once the snapshot has been fully transmitted by `RaftNetwork::full_snapshot()`, the task signals an event back to `ReplicationCore`. Subsequently, `ReplicationCore` informs `RaftCore` of the event, allowing it to acknowledge the completion of the snapshot transmission. Other changes: - `ReplicationCore` has two `RaftNetwork`s, one for log replication and heartbeat, the other for snapshot only. - `ReplicationClosed` becomes a public error for notifying the application implemented sender that a snapshot replication is canceled. - `StreamingError` is introduced as a container of errors that may occur in application defined snapshot transmission, including local IO error, network errors, errors returned by remote peer and `ReplicationClosed`. - The `SnapshotResponse` type is introduced to differentiate it from the `InstallSnapshotResponse`, which is used for chunk-based responses. - Added: [907f5f74](https://github.com/datafuselabs/openraft/commit/907f5f7494f073a6d1a844cf4ef05d314d76d7a8) feature flag `generic-snapshot-data`; by 张炎泼; 2024-02-16 Add feature flag `generic-snapshot-data`: when enabled, `SnapshotData` does not have `AsyncSeek + AsyncRead + AsyncWrite` bound. This enables application to define their own snapshot format and transmission protocol. If this feature flag is not eabled, no changes are required for application to upgrade Openraft. On the sending end(leader that sends snapshot to follower): - Without `generic-snapshot-data`: `RaftNetwork::snapshot()` provides a default implementation that invokes the chunk based API `RaftNetwork::install_snapshot()` for transmit. - With `generic-snapshot-data` enabled: `RaftNetwork::snapshot()` must be implemented to provide application customized snapshot transmission. Application does not need to implement `RaftNetwork::install_snapshot()`. On the receiving end(follower): - `Raft::install_snapshot()` is available only when `generic-snapshot-data` is disabled. Add an example `examples/raft-kv-memstore-generic-snapshot-data` with `generic-snapshot-data` enabled. In this example snapshot is transmitted without fragmentation, i.e., via `RaftNetwork::snapshot()`. The chunk based API `RaftNetwork::install_snapshot()` is not used. In a production scenario, a snapshot can be transmitted in arbitrary manner. - Fix: [#&#8203;606](https://github.com/datafuselabs/openraft/issues/606) - Fix: [#&#8203;209](https://github.com/datafuselabs/openraft/issues/209) - Added: [884f0da6](https://github.com/datafuselabs/openraft/commit/884f0da65ec10ce5777165e6906c61c326f2394b) add trait `RaftLogStorageExt` to provide additional raft-log methods; by 张炎泼; 2024-03-04 The `RaftLogReaderExt::blocking_append()` method enables the caller to append logs to storage in a blocking manner, eliminating the need to create and await a callback. This method simplifies the process of writing tests. ##### Fixed: - Fixed: [86b46a08](https://github.com/datafuselabs/openraft/commit/86b46a08090b44511ae481fad8c32ea805ac43d2) restore replication progress when a leader starts up ([#&#8203;884](https://github.com/datafuselabs/openraft/issues/884)); by 张炎泼; 2023-06-29 As a leader, the replication progress to itself should be restored upon startup. And if this leader is the only node in a cluster, it should re-apply all of the logs to state machine at once. - Fix: [#&#8203;883](https://github.com/datafuselabs/openraft/issues/883) - Fixed: [97254a31](https://github.com/datafuselabs/openraft/commit/97254a31c673e52429ee7187de96fd2ea2a5ce98) Do not report `snapshot.last_log_id` to metrics until snapshot is finished building/installing; by 张炎泼; 2023-10-18 Before this commit `RaftMetrics.snapshot` contains the last log id of a snapshot that is **going** to install. Therefore there is chance the metrics is updated but the store does not. In this commit, `RaftMetrics.snapshot` will only be updated when a snapshot is finished building or installing, by adding a new field `snpashot` to `IOState` for tracking persisted snapshot meta data. - Fix: [#&#8203;912](https://github.com/datafuselabs/openraft/issues/912) - Fixed: [ffae5224](https://github.com/datafuselabs/openraft/commit/ffae522425f9a55b1ab4d6ce866d469827932627) `AsyncReadExt::read_buf()` only reads at most 2MB per call; by 张炎泼; 2023-11-08 When streaming a snapshot chunk, it should repeatly `read_buf()` until `snapshot_max_chunk_size` is full or read EOF. - Fixed: [f41729a1](https://github.com/datafuselabs/openraft/commit/f41729a18ec147d24a8d00021f619b517aa1bab1) End `tick_loop()` when the receiver is gone.; by Ivan Schréter; 2023-11-13 Currently, `tick_loop()` would keep printing the trace message every tick even when the receiver (Raft main loop) is gone in this form: `INFO openraft::core::tick: .../tick.rs:70: Tick fails to send, receiving end quit: channel closed` If the tick message fails to send, then terminate the loop, since every future message will fail to send as well. Also adjust the trace message to better describe what happened. - Fixed: [0799972e](https://github.com/datafuselabs/openraft/commit/0799972ebeadafbe7a623ed7d74bcda65d342751) Split serde bound for `RaftError` into serialize and deserialize; by Thomas Van Strydonck; 2024-01-16 ##### Improved: - Improved: [06b431bf](https://github.com/datafuselabs/openraft/commit/06b431bf38fbde146e950ad34c4afa1556b48288) replace `async_trait` with RPITIT; by Josh Griffith; 2024-01-28 ### [`v0.8.9`](https://github.com/databendlabs/openraft/releases/tag/v0.8.9) [Compare Source](https://github.com/datafuselabs/openraft/compare/v0.8.8...v0.8.9) #### What's Changed - Feature: define custom Entry type for raft log by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/720 - Fix: trait RaftLogId should be public by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/726 - Change: StoreBuilder does not need to run a test, it only needs to build a store by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/730 - Feature: add methods to StorageIOError to simplify error creation by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/738 - Change: remove `Clone` from trait `AppData` by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/740 - Change: instead of a slice, `RaftStorage::append_to_log()` now accepts an `IntoIterator` by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/742 - Improve: follower stores the accepted log id by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/748 - Improve: send AppendEntries response before committing entries by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/751 - Change: remove unused trait RaftStorageDebug by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/759 - Change: remove defensive check utilities by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/761 - Change: move `RaftStateMachine` out of `RaftStorage` by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/763 - Improve: move state machine operations to another task by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/767 - Fix: if the application does not persist snapshot, build a snapshot when starting up by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/768 - Improve: getting a snapshot does not block RaftCore task by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/773 - Fix: debug level check by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/780 - Improve: reduce rate to flush metrics by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/782 - Change: `RaftMetrics.replication` type to `BTreeMap<NodeId, Option<LogId>>` by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/785 - Feature: add backoff strategy for unreachable nodes by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/779 - Improve: create a channel `notify` specifically for interal messages by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/794 - Change: move snapshot type definition from storage traits to `RaftTypeConfig` by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/799 - Improve: move receiving snapshot chunk to sm::Worker by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/803 - Feature: add RaftMetrics::purged to report the last purged log id by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/809 - Feature: add Wait::purged() to wait for purged to become the expected by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/810 - Fix: replication should be able to shutdown when replicating snapshot to unreachable node by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/811 - Feature: add `RaftMetrics.vote`, `Wait::vote()` by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/815 - Improve: build snapshot in anohter task by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/816 - Feature: new RaftNetwork API with argument RCPOption by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/825 - Feature: `RaftNetwork::send_append_entries()` can return PartialSuccess by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/831 - Change: remove unused error CommittedAdvanceTooMany by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/838 - Fix: add_learner() should block forever by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/847 - Feature: leader lease by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/848 - Feature: add SnapshotPolicy::Never by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/854 - Feature: add Raft::purge_log() by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/855 - Improve: IntoIterator::IntoIter should be Send by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/868 - Improve: impl Clone for Raft does not require Clone for its type parameters by [@&#8203;drmingdrmer](https://github.com/drmingdrmer) in https://github.com/datafuselabs/openraft/pull/872 #### New Contributors - [@&#8203;HHoflittlefish777](https://github.com/HHoflittlefish777) made their first contribution in https://github.com/datafuselabs/openraft/pull/842 - [@&#8203;leiysky](https://github.com/leiysky) made their first contribution in https://github.com/datafuselabs/openraft/pull/849 **Full Changelog**: https://github.com/datafuselabs/openraft/compare/v0.8.3...v0.8.9 </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4zOTguMiIsInVwZGF0ZWRJblZlciI6IjM4LjEyMi4wIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbInJlbm92YXRlLWJvdCJdfQ==-->
renovate-bot added the
renovate-bot
label 2024-06-07 22:31:39 +05:30
renovate-bot force-pushed renovate/openraft-0.x from 498b7157d5 to 35acb1c818 2024-06-08 01:00:49 +05:30 Compare
renovate-bot force-pushed renovate/openraft-0.x from 35acb1c818 to 5c9ec4f34f 2024-07-22 19:31:23 +05:30 Compare
renovate-bot force-pushed renovate/openraft-0.x from 5c9ec4f34f to 3c4f1116a9 2024-08-30 12:09:46 +05:30 Compare
renovate-bot force-pushed renovate/openraft-0.x from 3c4f1116a9 to 8f515cd882 2024-09-13 18:04:40 +05:30 Compare
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin renovate/openraft-0.x:renovate/openraft-0.x
git checkout renovate/openraft-0.x

Merge

Merge the changes and update on Forgejo.
git checkout master
git merge --no-ff renovate/openraft-0.x
git checkout master
git merge --ff-only renovate/openraft-0.x
git checkout renovate/openraft-0.x
git rebase master
git checkout master
git merge --no-ff renovate/openraft-0.x
git checkout master
git merge --squash renovate/openraft-0.x
git checkout master
git merge --ff-only renovate/openraft-0.x
git checkout master
git merge renovate/openraft-0.x
git push origin master
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: mCaptcha/dcache#39
No description provided.