diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e4e3c8a93..2eb4d6c02 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -15,7 +15,7 @@ jobs: matrix: include: - toolchain: "nightly" - features: "bench,serde,bt,singlethreaded" + features: "bench,serde,bt,singlethreaded,monoio" steps: - name: Setup | Checkout diff --git a/Cargo.toml b/Cargo.toml index 17dd84df9..f559d7f2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ derive_more = { version="0.99.9" } futures = "0.3" lazy_static = "1.4.0" maplit = "1.0.2" +monoio = "0.2.2" pretty_assertions = "1.0.0" proc-macro2 = "1.0" quote = "1.0" @@ -38,7 +39,7 @@ tokio = { version="1.8", default-features=false, features=["fs", "io-util", "mac tracing = { version = "0.1.40" } tracing-appender = "0.2.0" tracing-futures = "0.2.4" -tracing-subscriber = { version = "0.3.3", features=["env-filter"] } +tracing-subscriber = { version = "0.3.18", features=["env-filter"] } validit = { version = "0.2.2" } [workspace] diff --git a/openraft/Cargo.toml b/openraft/Cargo.toml index 4b3ad2d4b..0044a37b9 100644 --- a/openraft/Cargo.toml +++ b/openraft/Cargo.toml @@ -26,6 +26,7 @@ rand = { workspace = true } serde = { workspace = true, optional = true } serde_json = { workspace = true, optional = true } tempfile = { workspace = true, optional = true } +monoio = { workspace = true, optional = true } thiserror = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } @@ -78,6 +79,9 @@ compat = [] compat-07 = ["compat", "serde", "dep:or07", "compat-07-testing"] compat-07-testing = ["dep:tempfile", "anyhow", "dep:serde_json"] +monoio = ["dep:monoio", "singlethreaded"] +monoio-sync = ["dep:monoio", "monoio/sync"] + # Allows an application to implement a custom the v2 storage API. # See `openraft::storage::v2` for more details. # V2 API are unstable and may change in the future. @@ -115,6 +119,7 @@ generic-snapshot-data = [] tracing-log = [ "tracing/log" ] # default = ["single-term-leader"] +# default = ["monoio"] [package.metadata.docs.rs] diff --git a/openraft/src/async_runtime.rs b/openraft/src/async_runtime.rs index 5e9c73e2a..adeb54dfb 100644 --- a/openraft/src/async_runtime.rs +++ b/openraft/src/async_runtime.rs @@ -133,3 +133,78 @@ impl AsyncRuntime for TokioRuntime { rand::thread_rng() } } + +#[cfg(feature = "monoio")] +pub mod monoio { + use std::fmt::Debug; + use std::future::Future; + use std::time::Duration; + + use crate::AsyncRuntime; + use crate::OptionalSend; + + #[derive(Debug, Default)] + pub struct MonoioRuntime; + + pub type MonoioInstant = monoio::time::Instant; + + impl crate::Instant for monoio::time::Instant { + #[inline] + fn now() -> Self { + monoio::time::Instant::now() + } + } + + impl AsyncRuntime for MonoioRuntime { + type JoinError = crate::error::Infallible; + type JoinHandle = monoio::task::JoinHandle>; + type Sleep = monoio::time::Sleep; + type Instant = MonoioInstant; + type TimeoutError = monoio::time::error::Elapsed; + type Timeout + OptionalSend> = monoio::time::Timeout; + type ThreadLocalRng = rand::rngs::ThreadRng; + + #[inline] + fn spawn(future: T) -> Self::JoinHandle + where + T: Future + OptionalSend + 'static, + T::Output: OptionalSend + 'static, + { + monoio::spawn(async move { Ok(future.await) }) + } + + #[inline] + fn sleep(duration: Duration) -> Self::Sleep { + monoio::time::sleep(duration) + } + + #[inline] + fn sleep_until(deadline: Self::Instant) -> Self::Sleep { + monoio::time::sleep_until(deadline) + } + + #[inline] + fn timeout + OptionalSend>(duration: Duration, future: F) -> Self::Timeout { + monoio::time::timeout(duration, future) + } + + #[inline] + fn timeout_at + OptionalSend>( + deadline: Self::Instant, + future: F, + ) -> Self::Timeout { + monoio::time::timeout_at(deadline, future) + } + + #[inline] + fn is_panic(_join_error: &Self::JoinError) -> bool { + // A monoio task shouldn't panic or it would bubble the panic in case of a join + false + } + + #[inline] + fn thread_rng() -> Self::ThreadLocalRng { + rand::thread_rng() + } + } +} diff --git a/openraft/src/lib.rs b/openraft/src/lib.rs index 329897cd8..bf33ef6e7 100644 --- a/openraft/src/lib.rs +++ b/openraft/src/lib.rs @@ -75,6 +75,7 @@ pub use network::RaftNetwork; pub use network::RaftNetworkFactory; pub use type_config::RaftTypeConfig; +#[cfg(feature = "monoio")] pub use crate::async_runtime::monoio; pub use crate::async_runtime::AsyncRuntime; pub use crate::async_runtime::TokioRuntime; pub use crate::change_members::ChangeMembers; diff --git a/tests/Cargo.toml b/tests/Cargo.toml index ce6d7bd17..82c9728cb 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -41,3 +41,4 @@ tracing-subscriber = { workspace = true } bt = ["openraft/bt"] single-term-leader = ["openraft/single-term-leader"] loosen-follower-log-revert = ["openraft/loosen-follower-log-revert"] +monoio = ["openraft/monoio"]