From 06b431bf38fbde146e950ad34c4afa1556b48288 Mon Sep 17 00:00:00 2001 From: Josh Griffith Date: Sun, 28 Jan 2024 00:40:28 -0600 Subject: [PATCH] Perf: replace async_trait with RPITIT --- Cargo.toml | 4 +- cluster_benchmark/tests/benchmark/network.rs | 3 - cluster_benchmark/tests/benchmark/store.rs | 5 - .../tests/benchmark/store/test.rs | 3 +- .../src/network.rs | 3 - .../src/store.rs | 5 - .../src/network/raft_network_impl.rs | 3 - examples/raft-kv-memstore/src/store/mod.rs | 5 - .../src/network/raft_network_impl.rs | 3 - examples/raft-kv-rocksdb/src/store.rs | 5 - macros/Cargo.toml | 7 +- macros/src/lib.rs | 103 +++++++++++++++--- memstore/src/lib.rs | 4 - openraft/Cargo.toml | 3 +- openraft/src/compat/compat07.rs | 5 +- openraft/src/compat/testing.rs | 4 +- openraft/src/core/raft_core.rs | 2 - .../src/docs/feature_flags/feature-flags.md | 2 +- openraft/src/lib.rs | 1 - openraft/src/storage/adapter.rs | 4 - openraft/src/testing/store_builder.rs | 5 +- rocksstore-compat07/Cargo.toml | 1 - rocksstore-compat07/src/compatibility_test.rs | 2 - rocksstore-compat07/src/lib.rs | 4 - rocksstore-compat07/src/test.rs | 3 +- rocksstore/Cargo.toml | 1 - rocksstore/src/lib.rs | 4 - rocksstore/src/test.rs | 5 +- sledstore/Cargo.toml | 1 - sledstore/src/lib.rs | 4 - sledstore/src/test.rs | 2 - stores/rocksstore-v2/Cargo.toml | 1 - stores/rocksstore-v2/src/lib.rs | 6 +- stores/rocksstore-v2/src/test.rs | 5 +- tests/tests/fixtures/mod.rs | 3 - 35 files changed, 108 insertions(+), 113 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8ef3215c6..7ea4db3db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,6 @@ repository = "https://github.com/datafuselabs/openraft" anyerror = { version = "0.1.10" } anyhow = "1.0.63" async-entry = "0.3.1" -async-trait = "0.1.36" byte-unit = "4.0.12" bytes = "1.0" clap = { version = "4.1.11", features = ["derive", "env"] } @@ -27,9 +26,12 @@ futures = "0.3" lazy_static = "1.4.0" maplit = "1.0.2" pretty_assertions = "1.0.0" +proc-macro2 = "1.0" +quote = "1.0" rand = "0.8" serde = { version="1.0.114", features=["derive", "rc"]} serde_json = "1.0.57" +syn = "2.0" tempfile = { version = "3.4.0" } thiserror = "1.0.49" tokio = { version="1.8", default-features=false, features=["fs", "io-util", "macros", "rt", "rt-multi-thread", "sync", "time"] } diff --git a/cluster_benchmark/tests/benchmark/network.rs b/cluster_benchmark/tests/benchmark/network.rs index c4ab046d6..ff16edcce 100644 --- a/cluster_benchmark/tests/benchmark/network.rs +++ b/cluster_benchmark/tests/benchmark/network.rs @@ -7,7 +7,6 @@ use std::sync::Arc; use std::sync::Mutex; use std::time::Duration; -use openraft::async_trait::async_trait; use openraft::error::InstallSnapshotError; use openraft::error::RPCError; use openraft::error::RaftError; @@ -80,7 +79,6 @@ impl Router { } } -#[async_trait] impl RaftNetworkFactory for Router { type Network = Network; @@ -97,7 +95,6 @@ pub struct Network { target_raft: BenchRaft, } -#[async_trait] impl RaftNetwork for Network { async fn append_entries( &mut self, diff --git a/cluster_benchmark/tests/benchmark/store.rs b/cluster_benchmark/tests/benchmark/store.rs index 88e5fc95c..49fbe54fc 100644 --- a/cluster_benchmark/tests/benchmark/store.rs +++ b/cluster_benchmark/tests/benchmark/store.rs @@ -8,7 +8,6 @@ use std::sync::atomic::AtomicU64; use std::sync::atomic::Ordering; use std::sync::Arc; -use openraft::async_trait::async_trait; use openraft::storage::LogFlushed; use openraft::storage::LogState; use openraft::storage::RaftLogReader; @@ -100,7 +99,6 @@ impl StateMachineStore { } } -#[async_trait] impl RaftLogReader for Arc { async fn try_get_log_entries + Clone + Debug + Send + Sync>( &mut self, @@ -118,7 +116,6 @@ impl RaftLogReader for Arc { } } -#[async_trait] impl RaftSnapshotBuilder for Arc { #[tracing::instrument(level = "trace", skip(self))] async fn build_snapshot(&mut self) -> Result, StorageError> { @@ -170,7 +167,6 @@ impl RaftSnapshotBuilder for Arc { } } -#[async_trait] impl RaftLogStorage for Arc { async fn get_log_state(&mut self) -> Result, StorageError> { let log = self.log.read().await; @@ -244,7 +240,6 @@ impl RaftLogStorage for Arc { } } -#[async_trait] impl RaftStateMachine for Arc { async fn applied_state( &mut self, diff --git a/cluster_benchmark/tests/benchmark/store/test.rs b/cluster_benchmark/tests/benchmark/store/test.rs index 42f538168..8ed495d31 100644 --- a/cluster_benchmark/tests/benchmark/store/test.rs +++ b/cluster_benchmark/tests/benchmark/store/test.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use openraft::async_trait::async_trait; use openraft::testing::StoreBuilder; use openraft::testing::Suite; use openraft::StorageError; @@ -11,7 +10,7 @@ use crate::store::StateMachineStore; use crate::store::TypeConfig; struct Builder {} -#[async_trait] + impl StoreBuilder, Arc> for Builder { async fn build(&self) -> Result<((), Arc, Arc), StorageError> { let log_store = LogStore::new_async().await; diff --git a/examples/raft-kv-memstore-singlethreaded/src/network.rs b/examples/raft-kv-memstore-singlethreaded/src/network.rs index a79341392..87f653f14 100644 --- a/examples/raft-kv-memstore-singlethreaded/src/network.rs +++ b/examples/raft-kv-memstore-singlethreaded/src/network.rs @@ -1,4 +1,3 @@ -use openraft::add_async_trait; use openraft::error::InstallSnapshotError; use openraft::error::RemoteError; use openraft::raft::AppendEntriesRequest; @@ -21,7 +20,6 @@ pub struct Connection { target: NodeId, } -#[add_async_trait] impl RaftNetworkFactory for Router { type Network = Connection; @@ -33,7 +31,6 @@ impl RaftNetworkFactory for Router { } } -#[add_async_trait] impl RaftNetwork for Connection { async fn send_append_entries( &mut self, diff --git a/examples/raft-kv-memstore-singlethreaded/src/store.rs b/examples/raft-kv-memstore-singlethreaded/src/store.rs index ff66c1c1d..425130e19 100644 --- a/examples/raft-kv-memstore-singlethreaded/src/store.rs +++ b/examples/raft-kv-memstore-singlethreaded/src/store.rs @@ -6,7 +6,6 @@ use std::marker::PhantomData; use std::ops::RangeBounds; use std::rc::Rc; -use openraft::add_async_trait; use openraft::storage::LogFlushed; use openraft::storage::LogState; use openraft::storage::RaftLogStorage; @@ -120,7 +119,6 @@ pub struct LogStore { vote: RefCell>>, } -#[add_async_trait] impl RaftLogReader for Rc { async fn try_get_log_entries + Clone + Debug>( &mut self, @@ -132,7 +130,6 @@ impl RaftLogReader for Rc { } } -#[add_async_trait] impl RaftSnapshotBuilder for Rc { #[tracing::instrument(level = "trace", skip(self))] async fn build_snapshot(&mut self) -> Result, StorageError> { @@ -184,7 +181,6 @@ impl RaftSnapshotBuilder for Rc { } } -#[add_async_trait] impl RaftStateMachine for Rc { type SnapshotBuilder = Self; @@ -282,7 +278,6 @@ impl RaftStateMachine for Rc { } } -#[add_async_trait] impl RaftLogStorage for Rc { type LogReader = Self; diff --git a/examples/raft-kv-memstore/src/network/raft_network_impl.rs b/examples/raft-kv-memstore/src/network/raft_network_impl.rs index 855d16474..cf2ab8707 100644 --- a/examples/raft-kv-memstore/src/network/raft_network_impl.rs +++ b/examples/raft-kv-memstore/src/network/raft_network_impl.rs @@ -1,4 +1,3 @@ -use async_trait::async_trait; use openraft::error::InstallSnapshotError; use openraft::error::NetworkError; use openraft::error::RemoteError; @@ -59,7 +58,6 @@ impl Network { // NOTE: This could be implemented also on `Arc`, but since it's empty, implemented // directly. -#[async_trait] impl RaftNetworkFactory for Network { type Network = NetworkConnection; @@ -78,7 +76,6 @@ pub struct NetworkConnection { target_node: BasicNode, } -#[async_trait] impl RaftNetwork for NetworkConnection { async fn send_append_entries( &mut self, diff --git a/examples/raft-kv-memstore/src/store/mod.rs b/examples/raft-kv-memstore/src/store/mod.rs index 56aeb7a7f..4f92c75ac 100644 --- a/examples/raft-kv-memstore/src/store/mod.rs +++ b/examples/raft-kv-memstore/src/store/mod.rs @@ -5,7 +5,6 @@ use std::ops::RangeBounds; use std::sync::Arc; use std::sync::Mutex; -use openraft::async_trait::async_trait; use openraft::storage::LogFlushed; use openraft::storage::LogState; use openraft::storage::RaftLogStorage; @@ -101,7 +100,6 @@ pub struct LogStore { vote: RwLock>>, } -#[async_trait] impl RaftLogReader for Arc { async fn try_get_log_entries + Clone + Debug + Send + Sync>( &mut self, @@ -113,7 +111,6 @@ impl RaftLogReader for Arc { } } -#[async_trait] impl RaftSnapshotBuilder for Arc { #[tracing::instrument(level = "trace", skip(self))] async fn build_snapshot(&mut self) -> Result, StorageError> { @@ -165,7 +162,6 @@ impl RaftSnapshotBuilder for Arc { } } -#[async_trait] impl RaftStateMachine for Arc { type SnapshotBuilder = Self; @@ -263,7 +259,6 @@ impl RaftStateMachine for Arc { } } -#[async_trait] impl RaftLogStorage for Arc { type LogReader = Self; diff --git a/examples/raft-kv-rocksdb/src/network/raft_network_impl.rs b/examples/raft-kv-rocksdb/src/network/raft_network_impl.rs index ecb9bf491..a3cc85f55 100644 --- a/examples/raft-kv-rocksdb/src/network/raft_network_impl.rs +++ b/examples/raft-kv-rocksdb/src/network/raft_network_impl.rs @@ -1,7 +1,6 @@ use std::any::Any; use std::fmt::Display; -use async_trait::async_trait; use openraft::error::InstallSnapshotError; use openraft::error::NetworkError; use openraft::error::RPCError; @@ -29,7 +28,6 @@ pub struct Network {} // NOTE: This could be implemented also on `Arc`, but since it's empty, implemented // directly. -#[async_trait] impl RaftNetworkFactory for Network { type Network = NetworkConnection; @@ -112,7 +110,6 @@ fn to_error(e: toy_rpc::Error, target: N // = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#blocks_in_conditions // = note: `#[warn(clippy::blocks_in_conditions)]` on by default #[allow(clippy::blocks_in_conditions)] -#[async_trait] impl RaftNetwork for NetworkConnection { #[tracing::instrument(level = "debug", skip_all, err(Debug))] async fn send_append_entries( diff --git a/examples/raft-kv-rocksdb/src/store.rs b/examples/raft-kv-rocksdb/src/store.rs index 6aba98856..2e7c7f421 100644 --- a/examples/raft-kv-rocksdb/src/store.rs +++ b/examples/raft-kv-rocksdb/src/store.rs @@ -9,7 +9,6 @@ use async_std::sync::RwLock; use byteorder::BigEndian; use byteorder::ReadBytesExt; use byteorder::WriteBytesExt; -use openraft::async_trait::async_trait; use openraft::storage::LogFlushed; use openraft::storage::LogState; use openraft::storage::RaftLogStorage; @@ -99,7 +98,6 @@ pub struct StateMachineData { pub kvs: Arc>>, } -#[async_trait] impl RaftSnapshotBuilder for StateMachineStore { async fn build_snapshot(&mut self) -> Result, StorageError> { let last_applied_log = self.data.last_applied_log_id; @@ -198,7 +196,6 @@ impl StateMachineStore { } } -#[async_trait] impl RaftStateMachine for StateMachineStore { type SnapshotBuilder = Self; @@ -370,7 +367,6 @@ impl LogStore { } } -#[async_trait] impl RaftLogReader for LogStore { async fn try_get_log_entries + Clone + Debug + Send + Sync>( &mut self, @@ -399,7 +395,6 @@ impl RaftLogReader for LogStore { } } -#[async_trait] impl RaftLogStorage for LogStore { type LogReader = Self; diff --git a/macros/Cargo.toml b/macros/Cargo.toml index d85c6c885..b63d54c38 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -15,7 +15,12 @@ repository = { workspace = true } [lib] proc-macro = true +[dependencies] +proc-macro2 = { workspace = true } +quote = { workspace = true } +syn = { workspace = true, features = ["full"] } + [features] -# Do not use `async_trait` and do not add `Send` bounds. +# Do not add `Send` bounds. singlethreaded = [] diff --git a/macros/src/lib.rs b/macros/src/lib.rs index be6213e9f..a984c8cd7 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,28 +1,95 @@ use proc_macro::TokenStream; +use quote::quote; +use syn::parse2; +use syn::parse_macro_input; +use syn::parse_str; +use syn::token::RArrow; +use syn::Item; +use syn::ReturnType; +use syn::TraitItem; +use syn::Type; -/// This macro emits `#[async_trait::async_trait]` if the `singlethreaded` feature is disabled. +/// This proc macro attribute optionally adds `Send` bounds to a trait. /// -/// Starting from Rust 1.75.0, the `async_fn_in_trait` language feature is generally available -/// that allows traits to contain asynchronous methods and associated functions. However, the -/// feature has several known issues that are mainly related to Rust compiler's abilities to infer -/// `Send` bounds of associated types: [`90696``](https://github.com/rust-lang/rust/issues/90696). +/// By default, `Send` bounds will be added to the trait and to the return bounds of any async +/// functions defined withing the trait. /// -/// Therefore, if a trait requires `Send` bounds in its associated data types, this macro -/// circumvents the compiler shortcomings by using the -/// [`async-trait`](https://crates.io/crates/async-trait) crate which boxes return -/// [`Future`](https://doc.rust-lang.org/std/future/trait.Future.html) types of all the -/// asynchronous methods and associated functions of the trait. +/// If the `singlethreaded` feature is enabled, the trait definition remains the same without any +/// added `Send` bounds. +/// +/// # Example +/// +/// ``` +/// use macros::add_async_trait; +/// +/// #[add_async_trait] +/// trait MyTrait { +/// async fn my_method(&self) -> Result<(), String>; +/// } +/// ``` +/// +/// Note: This proc macro can only be used with traits. +/// +/// # Panics +/// +/// This proc macro will panic if used on anything other than trait definitions. #[proc_macro_attribute] pub fn add_async_trait(_attr: TokenStream, item: TokenStream) -> TokenStream { if cfg!(feature = "singlethreaded") { - // `async_fn_in_trait` requires the user to explicitly specify the `Send` bound for public - // trait methods, however the `singlethreaded` feature renders the requirement irrelevant. - let mut output = "#[allow(async_fn_in_trait)]".parse::().unwrap(); - output.extend(item); - output + allow_non_send_bounds(item) } else { - let mut output = "#[async_trait::async_trait]".parse::().unwrap(); - output.extend(item); - output + add_send_bounds(item) + } +} + +fn allow_non_send_bounds(item: TokenStream) -> TokenStream { + // `async_fn_in_trait` requires the user to explicitly specify the `Send` bound for public + // trait methods, however the `singlethreaded` feature renders the requirement irrelevant. + let item: proc_macro2::TokenStream = item.into(); + quote! { + #[allow(async_fn_in_trait)] + #item + } + .into() +} + +fn add_send_bounds(item: TokenStream) -> TokenStream { + let send_bound = parse_str("Send").unwrap(); + let default_return_type: Box = parse_str("impl std::future::Future + Send").unwrap(); + + match parse_macro_input!(item) { + Item::Trait(mut input) => { + // add `Send` bound to the trait + input.supertraits.push(send_bound); + + for item in input.items.iter_mut() { + // for each async function definition + let TraitItem::Fn(function) = item else { continue }; + if function.sig.asyncness.is_none() { + continue; + }; + + // remove async from signature + function.sig.asyncness = None; + + // wrap the return type in a `Future` + function.sig.output = match &function.sig.output { + ReturnType::Default => ReturnType::Type(RArrow::default(), default_return_type.clone()), + ReturnType::Type(arrow, t) => { + let tokens = quote!(impl std::future::Future + Send); + ReturnType::Type(*arrow, parse2(tokens).unwrap()) + } + }; + + // if a body is defined, wrap it in an async block + let Some(body) = &function.default else { continue }; + let body = parse2(quote!({ async move #body })).unwrap(); + function.default = Some(body); + } + + quote!(#input).into() + } + + _ => panic!("add_async_trait can only be used with traits"), } } diff --git a/memstore/src/lib.rs b/memstore/src/lib.rs index ef3c51024..39fa9997f 100644 --- a/memstore/src/lib.rs +++ b/memstore/src/lib.rs @@ -11,7 +11,6 @@ use std::ops::RangeBounds; use std::sync::Arc; use std::sync::Mutex; -use openraft::async_trait::async_trait; use openraft::storage::LogState; use openraft::storage::RaftLogReader; use openraft::storage::RaftSnapshotBuilder; @@ -205,7 +204,6 @@ impl Default for MemStore { } } -#[async_trait] impl RaftLogReader for Arc { async fn try_get_log_entries + Clone + Debug + Send + Sync>( &mut self, @@ -224,7 +222,6 @@ impl RaftLogReader for Arc { } } -#[async_trait] impl RaftSnapshotBuilder for Arc { #[tracing::instrument(level = "trace", skip(self))] async fn build_snapshot(&mut self) -> Result, StorageError> { @@ -290,7 +287,6 @@ impl RaftSnapshotBuilder for Arc { } } -#[async_trait] impl RaftStorage for Arc { async fn get_log_state(&mut self) -> Result, StorageError> { let log = self.log.read().await; diff --git a/openraft/Cargo.toml b/openraft/Cargo.toml index a3eb31ff2..c96a0b4cc 100644 --- a/openraft/Cargo.toml +++ b/openraft/Cargo.toml @@ -15,9 +15,9 @@ repository = { workspace = true } [dependencies] anyerror = { workspace = true } -async-trait = { workspace = true } anyhow = { workspace = true, optional = true } byte-unit = { workspace = true } +clap = { workspace = true } derive_more = { workspace = true } futures = { workspace = true } macros = { path = "../macros" } @@ -25,7 +25,6 @@ maplit = { workspace = true } rand = { workspace = true } serde = { workspace = true, optional = true } serde_json = { workspace = true, optional = true } -clap = { workspace = true } tempfile = { workspace = true, optional = true } thiserror = { workspace = true } tokio = { workspace = true } diff --git a/openraft/src/compat/compat07.rs b/openraft/src/compat/compat07.rs index 922e147c3..2ac6dd3b4 100644 --- a/openraft/src/compat/compat07.rs +++ b/openraft/src/compat/compat07.rs @@ -25,7 +25,6 @@ //! struct Builder07; //! struct BuilderLatest; //! -//! #[async_trait::async_trait] //! impl compat::testing::StoreBuilder07 for Builder07 { //! type D = rocksstore07::RocksRequest; //! type R = rocksstore07::RocksResponse; @@ -40,7 +39,6 @@ //! } //! } //! -//! #[async_trait::async_trait] //! impl compat::testing::StoreBuilder for BuilderLatest { //! type C = crate::Config; //! type S = Arc; @@ -87,6 +85,7 @@ pub use vote::Vote; pub mod testing { use std::path::Path; + use macros::add_async_trait; use maplit::btreemap; use maplit::btreeset; @@ -96,7 +95,7 @@ pub mod testing { use crate::log_id::RaftLogId; /// Build a v0.7 `RaftStorage` implementation for compatibility test. - #[async_trait::async_trait] + #[add_async_trait] pub trait StoreBuilder07 { type D: or07::AppData; type R: or07::AppDataResponse; diff --git a/openraft/src/compat/testing.rs b/openraft/src/compat/testing.rs index d3ed3bef3..efdbf5b49 100644 --- a/openraft/src/compat/testing.rs +++ b/openraft/src/compat/testing.rs @@ -4,8 +4,10 @@ use std::path::Path; +use macros::add_async_trait; + /// Build a latest `RaftStorage` implementation for compatibility test. -#[async_trait::async_trait] +#[add_async_trait] pub trait StoreBuilder { type C: crate::RaftTypeConfig; type S: crate::RaftStorage; diff --git a/openraft/src/core/raft_core.rs b/openraft/src/core/raft_core.rs index 5bd10d554..3e90e89bc 100644 --- a/openraft/src/core/raft_core.rs +++ b/openraft/src/core/raft_core.rs @@ -12,7 +12,6 @@ use anyerror::AnyError; use futures::stream::FuturesUnordered; use futures::StreamExt; use futures::TryFutureExt; -use macros::add_async_trait; use maplit::btreeset; use tokio::select; use tokio::sync::mpsc; @@ -1527,7 +1526,6 @@ where } } -#[add_async_trait] impl RaftRuntime for RaftCore where C: RaftTypeConfig, diff --git a/openraft/src/docs/feature_flags/feature-flags.md b/openraft/src/docs/feature_flags/feature-flags.md index 4970570c8..79ed37a9b 100644 --- a/openraft/src/docs/feature_flags/feature-flags.md +++ b/openraft/src/docs/feature_flags/feature-flags.md @@ -51,7 +51,7 @@ By default openraft enables no features. and other types to force the asynchronous runtime to spawn any tasks in the current thread. This is for any single-threaded application that never allows a raft instance to be shared among multiple threads. This feature relies on the `async_fn_in_trait` language feature that is officially supported from Rust 1.75.0. - If the feature is enabled, affected asynchronous trait methods and associated functions no longer use `async_trait`. + If the feature is enabled, affected asynchronous trait methods require `Send` bounds. In order to use the feature, `AsyncRuntime::spawn` should invoke `tokio::task::spawn_local` or equivalents.

diff --git a/openraft/src/lib.rs b/openraft/src/lib.rs index 1fc0f285a..329897cd8 100644 --- a/openraft/src/lib.rs +++ b/openraft/src/lib.rs @@ -69,7 +69,6 @@ mod try_as_ref; pub use anyerror; pub use anyerror::AnyError; -pub use async_trait; pub use macros::add_async_trait; pub use network::RPCTypes; pub use network::RaftNetwork; diff --git a/openraft/src/storage/adapter.rs b/openraft/src/storage/adapter.rs index 669c83f82..edd714f66 100644 --- a/openraft/src/storage/adapter.rs +++ b/openraft/src/storage/adapter.rs @@ -4,7 +4,6 @@ use std::ops::DerefMut; use std::ops::RangeBounds; use std::sync::Arc; -use macros::add_async_trait; use tokio::sync::RwLock; use tokio::sync::RwLockReadGuard; use tokio::sync::RwLockWriteGuard; @@ -98,7 +97,6 @@ where } } -#[add_async_trait] impl RaftLogReader for Adaptor where C: RaftTypeConfig, @@ -119,7 +117,6 @@ where { } -#[add_async_trait] impl RaftLogStorage for Adaptor where C: RaftTypeConfig, @@ -170,7 +167,6 @@ where } } -#[add_async_trait] impl RaftStateMachine for Adaptor where C: RaftTypeConfig, diff --git a/openraft/src/testing/store_builder.rs b/openraft/src/testing/store_builder.rs index 146b28d48..6e93d1a2c 100644 --- a/openraft/src/testing/store_builder.rs +++ b/openraft/src/testing/store_builder.rs @@ -1,6 +1,6 @@ #[cfg(not(feature = "storage-v2"))] use std::future::Future; -use async_trait::async_trait; +use macros::add_async_trait; #[cfg(not(feature = "storage-v2"))] use crate::storage::Adaptor; use crate::storage::RaftLogStorage; @@ -19,7 +19,7 @@ use crate::StorageError; /// /// By default `G` is a trivial guard `()`. To test a store that is backed by a folder on disk, `G` /// could be the dropper of the temp-dir that stores data. -#[async_trait] +#[add_async_trait] pub trait StoreBuilder: Send + Sync where C: RaftTypeConfig, @@ -32,7 +32,6 @@ where // Add a default implementation for async function that returns a [`RaftStorage`] implementation. #[cfg(not(feature = "storage-v2"))] -#[async_trait] impl StoreBuilder, Adaptor, ()> for F where F: Send + Sync, diff --git a/rocksstore-compat07/Cargo.toml b/rocksstore-compat07/Cargo.toml index b84c4bfd4..5969e9fcd 100644 --- a/rocksstore-compat07/Cargo.toml +++ b/rocksstore-compat07/Cargo.toml @@ -26,7 +26,6 @@ tracing = "0.1.29" [dev-dependencies] anyhow = { workspace = true } -async-trait = { version = "0.1.36" } tempfile = { version = "3.4.0" } tokio = { version = "1.25.0" } diff --git a/rocksstore-compat07/src/compatibility_test.rs b/rocksstore-compat07/src/compatibility_test.rs index 1ad102a09..f2dcd67ad 100644 --- a/rocksstore-compat07/src/compatibility_test.rs +++ b/rocksstore-compat07/src/compatibility_test.rs @@ -8,7 +8,6 @@ struct Builder07; /// A builder builds latest openraft based rocksstore. struct BuilderLatest; -#[async_trait::async_trait] impl compat::testing::StoreBuilder07 for Builder07 { type D = rocksstore07::RocksRequest; type R = rocksstore07::RocksResponse; @@ -26,7 +25,6 @@ impl compat::testing::StoreBuilder07 for Builder07 { } } -#[async_trait::async_trait] impl compat::testing::StoreBuilder for BuilderLatest { type C = crate::TypeConfig; type S = Arc; diff --git a/rocksstore-compat07/src/lib.rs b/rocksstore-compat07/src/lib.rs index 90b497d15..6ed07b393 100644 --- a/rocksstore-compat07/src/lib.rs +++ b/rocksstore-compat07/src/lib.rs @@ -32,7 +32,6 @@ use async_std::sync::RwLock; use byteorder::BigEndian; use byteorder::ReadBytesExt; use byteorder::WriteBytesExt; -use openraft::async_trait::async_trait; use openraft::compat::compat07; use openraft::compat::Upgrade; use openraft::AnyError; @@ -368,7 +367,6 @@ impl RocksStore { } } -#[async_trait] impl RaftLogReader for Arc { async fn try_get_log_entries + Clone + Debug + Send + Sync>( &mut self, @@ -402,7 +400,6 @@ impl RaftLogReader for Arc { } } -#[async_trait] impl RaftSnapshotBuilder for Arc { #[tracing::instrument(level = "trace", skip(self))] async fn build_snapshot(&mut self) -> Result, StorageError> { @@ -449,7 +446,6 @@ impl RaftSnapshotBuilder for Arc { } } -#[async_trait] impl RaftStorage for Arc { type LogReader = Self; type SnapshotBuilder = Self; diff --git a/rocksstore-compat07/src/test.rs b/rocksstore-compat07/src/test.rs index 378eb0d26..6e8e895b1 100644 --- a/rocksstore-compat07/src/test.rs +++ b/rocksstore-compat07/src/test.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use async_trait::async_trait; use openraft::storage::Adaptor; use openraft::testing::StoreBuilder; use openraft::testing::Suite; @@ -15,7 +14,7 @@ type LogStore = Adaptor>; type StateMachine = Adaptor>; struct RocksBuilder {} -#[async_trait] + impl StoreBuilder for RocksBuilder { async fn build(&self) -> Result<(TempDir, LogStore, StateMachine), StorageError> { let td = TempDir::new().expect("couldn't create temp dir"); diff --git a/rocksstore/Cargo.toml b/rocksstore/Cargo.toml index d4b7475a3..a94f31b6f 100644 --- a/rocksstore/Cargo.toml +++ b/rocksstore/Cargo.toml @@ -26,7 +26,6 @@ async-std = { version = "1.12.0", features = ["attributes", "tokio1"] } tracing = "0.1.29" [dev-dependencies] -async-trait = { version = "0.1.36" } tempfile = { version = "3.4.0" } [package.metadata.docs.rs] diff --git a/rocksstore/src/lib.rs b/rocksstore/src/lib.rs index 7cd8a25a5..bf4eb7162 100644 --- a/rocksstore/src/lib.rs +++ b/rocksstore/src/lib.rs @@ -15,7 +15,6 @@ use async_std::sync::RwLock; use byteorder::BigEndian; use byteorder::ReadBytesExt; use byteorder::WriteBytesExt; -use openraft::async_trait::async_trait; use openraft::storage::LogState; use openraft::storage::Snapshot; use openraft::AnyError; @@ -338,7 +337,6 @@ impl RocksStore { } } -#[async_trait] impl RaftLogReader for Arc { async fn try_get_log_entries + Clone + Debug + Send + Sync>( &mut self, @@ -371,7 +369,6 @@ impl RaftLogReader for Arc { } } -#[async_trait] impl RaftSnapshotBuilder for Arc { #[tracing::instrument(level = "trace", skip(self))] async fn build_snapshot(&mut self) -> Result, StorageError> { @@ -418,7 +415,6 @@ impl RaftSnapshotBuilder for Arc { } } -#[async_trait] impl RaftStorage for Arc { type LogReader = Self; type SnapshotBuilder = Self; diff --git a/rocksstore/src/test.rs b/rocksstore/src/test.rs index 3b6f6219e..f78e3d2f7 100644 --- a/rocksstore/src/test.rs +++ b/rocksstore/src/test.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use async_trait::async_trait; use openraft::storage::Adaptor; use openraft::testing::StoreBuilder; use openraft::testing::Suite; @@ -15,7 +14,7 @@ type LogStore = Adaptor>; type StateMachine = Adaptor>; struct RocksBuilder {} -#[async_trait] + impl StoreBuilder for RocksBuilder { async fn build(&self) -> Result<(TempDir, LogStore, StateMachine), StorageError> { let td = TempDir::new().expect("couldn't create temp dir"); @@ -28,14 +27,12 @@ impl StoreBuilder for RocksBuilder /// To customize a builder: /// /// ```ignore -/// use async_trait::async_trait; /// use openraft::testing::StoreBuilder; /// use crate::ClientRequest; /// use crate::ClientResponse; /// /// struct MemStoreBuilder {} /// -/// #[async_trait] /// impl StoreBuilder for MemStoreBuilder { /// async fn build(&self) -> MemStore { /// MemStore::new().await diff --git a/sledstore/Cargo.toml b/sledstore/Cargo.toml index 8787a82e3..f4cf7a10f 100644 --- a/sledstore/Cargo.toml +++ b/sledstore/Cargo.toml @@ -25,7 +25,6 @@ tracing = "0.1.29" [dev-dependencies] tempfile = { version = "3.4.0" } -async-trait = { version = "0.1.36" } [package.metadata.docs.rs] all-features = true diff --git a/sledstore/src/lib.rs b/sledstore/src/lib.rs index 757cd176e..1ac395adc 100644 --- a/sledstore/src/lib.rs +++ b/sledstore/src/lib.rs @@ -14,7 +14,6 @@ use async_std::sync::RwLock; use byteorder::BigEndian; use byteorder::ByteOrder; use byteorder::ReadBytesExt; -use openraft::async_trait::async_trait; use openraft::storage::LogState; use openraft::storage::Snapshot; use openraft::AnyError; @@ -384,7 +383,6 @@ impl SledStore { } } -#[async_trait] impl RaftLogReader for Arc { async fn try_get_log_entries + Clone + Debug + Send + Sync>( &mut self, @@ -418,7 +416,6 @@ impl RaftLogReader for Arc { } } -#[async_trait] impl RaftSnapshotBuilder for Arc { #[tracing::instrument(level = "trace", skip(self))] async fn build_snapshot(&mut self) -> Result, StorageError> { @@ -465,7 +462,6 @@ impl RaftSnapshotBuilder for Arc { } } -#[async_trait] impl RaftStorage for Arc { type LogReader = Self; type SnapshotBuilder = Self; diff --git a/sledstore/src/test.rs b/sledstore/src/test.rs index eebc5cb26..e45d7428a 100644 --- a/sledstore/src/test.rs +++ b/sledstore/src/test.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use async_trait::async_trait; use openraft::storage::Adaptor; use openraft::testing::StoreBuilder; use openraft::testing::Suite; @@ -21,7 +20,6 @@ pub fn test_sled_store() -> Result<(), StorageError> { type LogStore = Adaptor>; type StateMachine = Adaptor>; -#[async_trait] impl StoreBuilder for SledBuilder { async fn build(&self) -> Result<(TempDir, LogStore, StateMachine), StorageError> { let td = TempDir::new().expect("couldn't create temp dir"); diff --git a/stores/rocksstore-v2/Cargo.toml b/stores/rocksstore-v2/Cargo.toml index 948f17ba9..7c8cf7c1e 100644 --- a/stores/rocksstore-v2/Cargo.toml +++ b/stores/rocksstore-v2/Cargo.toml @@ -28,7 +28,6 @@ serde_json = "1.0.57" tracing = "0.1.29" [dev-dependencies] -async-trait = { version = "0.1.36" } tempfile = { version = "3.4.0" } [package.metadata.docs.rs] diff --git a/stores/rocksstore-v2/src/lib.rs b/stores/rocksstore-v2/src/lib.rs index 4f85945ee..0bc9d6768 100644 --- a/stores/rocksstore-v2/src/lib.rs +++ b/stores/rocksstore-v2/src/lib.rs @@ -18,7 +18,6 @@ use std::sync::Arc; use byteorder::BigEndian; use byteorder::ReadBytesExt; use byteorder::WriteBytesExt; -use openraft::async_trait::async_trait; use openraft::storage::LogFlushed; use openraft::storage::LogState; use openraft::storage::RaftLogStorage; @@ -231,7 +230,6 @@ impl RocksLogStore { } } -#[async_trait] impl RaftLogReader for RocksLogStore { async fn try_get_log_entries + Clone + Debug + Send + Sync>( &mut self, @@ -264,7 +262,6 @@ impl RaftLogReader for RocksLogStore { } } -#[async_trait] impl RaftSnapshotBuilder for RocksStateMachine { #[tracing::instrument(level = "trace", skip(self))] async fn build_snapshot(&mut self) -> Result, StorageError> { @@ -310,7 +307,6 @@ impl RaftSnapshotBuilder for RocksStateMachine { } } -#[async_trait] impl RaftLogStorage for RocksLogStore { type LogReader = Self; @@ -407,7 +403,7 @@ impl RaftLogStorage for RocksLogStore { Ok(()) } } -#[async_trait] + impl RaftStateMachine for RocksStateMachine { type SnapshotBuilder = Self; diff --git a/stores/rocksstore-v2/src/test.rs b/stores/rocksstore-v2/src/test.rs index aece3f9f5..3b5143b5c 100644 --- a/stores/rocksstore-v2/src/test.rs +++ b/stores/rocksstore-v2/src/test.rs @@ -1,4 +1,3 @@ -use async_trait::async_trait; use openraft::testing::StoreBuilder; use openraft::testing::Suite; use openraft::StorageError; @@ -10,7 +9,7 @@ use crate::RocksStateMachine; use crate::TypeConfig; struct RocksBuilder {} -#[async_trait] + impl StoreBuilder for RocksBuilder { async fn build(&self) -> Result<(TempDir, RocksLogStore, RocksStateMachine), StorageError> { let td = TempDir::new().expect("couldn't create temp dir"); @@ -21,14 +20,12 @@ impl StoreBuilder for Roc /// To customize a builder: /// /// ```ignore -/// use async_trait::async_trait; /// use openraft::testing::StoreBuilder; /// use crate::ClientRequest; /// use crate::ClientResponse; /// /// struct MemStoreBuilder {} /// -/// #[async_trait] /// impl StoreBuilder for MemStoreBuilder { /// async fn build(&self) -> MemStore { /// MemStore::new().await diff --git a/tests/tests/fixtures/mod.rs b/tests/tests/fixtures/mod.rs index 092a7f4db..1ef43ffa3 100644 --- a/tests/tests/fixtures/mod.rs +++ b/tests/tests/fixtures/mod.rs @@ -20,7 +20,6 @@ use anyerror::AnyError; use anyhow::Context; use lazy_static::lazy_static; use maplit::btreeset; -use openraft::async_trait::async_trait; use openraft::error::CheckIsLeaderError; use openraft::error::ClientWriteError; use openraft::error::Fatal; @@ -968,7 +967,6 @@ impl TypedRaftRouter { } } -#[async_trait] impl RaftNetworkFactory for TypedRaftRouter { type Network = RaftRouterNetwork; @@ -985,7 +983,6 @@ pub struct RaftRouterNetwork { owner: TypedRaftRouter, } -#[async_trait] impl RaftNetwork for RaftRouterNetwork { /// Send an AppendEntries RPC to the target Raft node (ยง5). async fn send_append_entries(