-
Notifications
You must be signed in to change notification settings - Fork 154
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature:
RaftNetwork::snapshot()
to send a complete snapshot
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::stream_snapshot`. The `stream_snapshot` mod provides a default chunk-based snapshot transmission mechanism, which can be overridden by creating a custom implementation of the `RaftNetwork::snapshot()` method. As part of this commit, `RaftNetwork::snapshot()` simply delegates to `stream_snapshot`. Developers may use `stream_snapshot` 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::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::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. --- - Part of #606
- Loading branch information
1 parent
23553ba
commit 4098c38
Showing
25 changed files
with
655 additions
and
176 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -355,7 +355,7 @@ jobs: | |
with: | ||
name: tests-feature-test | ||
path: | | ||
openraft/_log/ | ||
tests/_log/ | ||
lint: | ||
name: lint | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/// Replication is closed intentionally. | ||
/// | ||
/// No further replication action should be taken. | ||
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)] | ||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] | ||
#[error("Replication is closed: {reason}")] | ||
pub struct ReplicationClosed { | ||
reason: String, | ||
} | ||
|
||
impl ReplicationClosed { | ||
pub fn new(reason: impl ToString) -> Self { | ||
Self { | ||
reason: reason.to_string(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
use std::error::Error; | ||
|
||
use crate::error::NetworkError; | ||
use crate::error::RPCError; | ||
use crate::error::RaftError; | ||
use crate::error::RemoteError; | ||
use crate::error::ReplicationClosed; | ||
use crate::error::ReplicationError; | ||
use crate::error::Timeout; | ||
use crate::error::Unreachable; | ||
use crate::RaftTypeConfig; | ||
use crate::StorageError; | ||
|
||
/// Error occurred when streaming local data to a remote raft node. | ||
/// | ||
/// Thus this error includes storage error, network error, and remote error. | ||
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)] | ||
#[cfg_attr( | ||
feature = "serde", | ||
derive(serde::Serialize, serde::Deserialize), | ||
serde(bound(serialize = "E: serde::Serialize")), | ||
serde(bound(deserialize = "E: for <'d> serde::Deserialize<'d>")) | ||
)] | ||
pub enum StreamingError<C: RaftTypeConfig, E: Error> { | ||
/// The replication stream is closed intentionally. | ||
#[error(transparent)] | ||
Closed(#[from] ReplicationClosed), | ||
|
||
/// Storage error occurs when reading local data. | ||
#[error(transparent)] | ||
StorageError(#[from] StorageError<C::NodeId>), | ||
|
||
/// Timeout when streaming data to remote node. | ||
#[error(transparent)] | ||
Timeout(#[from] Timeout<C::NodeId>), | ||
|
||
/// The node is temporarily unreachable and should backoff before retrying. | ||
#[error(transparent)] | ||
Unreachable(#[from] Unreachable), | ||
|
||
/// Failed to send the RPC request and should retry immediately. | ||
#[error(transparent)] | ||
Network(#[from] NetworkError), | ||
|
||
/// Remote node returns an error. | ||
#[error(transparent)] | ||
RemoteError(#[from] RemoteError<C::NodeId, C::Node, E>), | ||
} | ||
|
||
impl<C: RaftTypeConfig, E> From<StreamingError<C, E>> for ReplicationError<C::NodeId, C::Node> | ||
where | ||
E: Error, | ||
RaftError<C::NodeId>: From<E>, | ||
{ | ||
fn from(e: StreamingError<C, E>) -> Self { | ||
match e { | ||
StreamingError::Closed(e) => ReplicationError::Closed(e), | ||
StreamingError::StorageError(e) => ReplicationError::StorageError(e), | ||
StreamingError::Timeout(e) => ReplicationError::RPCError(RPCError::Timeout(e)), | ||
StreamingError::Unreachable(e) => ReplicationError::RPCError(RPCError::Unreachable(e)), | ||
StreamingError::Network(e) => ReplicationError::RPCError(RPCError::Network(e)), | ||
StreamingError::RemoteError(e) => { | ||
let remote_err = RemoteError { | ||
target: e.target, | ||
target_node: e.target_node, | ||
source: RaftError::from(e.source), | ||
}; | ||
ReplicationError::RPCError(RPCError::RemoteError(remote_err)) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.