diff --git a/Cargo.toml b/Cargo.toml index f8bc5181..9537da96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ ] exclude = [ "benches", + "benches_smol", "benches_glommio", ] diff --git a/README.md b/README.md index 92d6e569..fd966610 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
- *macro-less and type-safe* APIs for intuitive and declarative code -- *multiple runtimes* are supported:`tokio`, `async-std`, `worker` (Cloudflare Workers) +- *multiple runtimes* are supported:`tokio`, `async-std`, `smol`, `glommio`, `worker` (Cloudflare Workers)
License @@ -66,12 +66,17 @@ Hello, your_name! ## Feature flags -### `"rt_tokio"`, `"rt_async-std"`, `"rt_glommio"`:native async runtime +### `"rt_tokio"`, `"rt_async-std"`, `"rt_smol"`, `"rt_glommio"` + +Currently, - [tokio](https://github.com/tokio-rs/tokio) - [async-std](https://github.com/async-rs/async-std) +- [smol](https://github.com/smol-rs/smol) - [glommio](https://github.com/DataDog/glommio) +are supported as async runtime. + ### `"rt_worker"`:Cloudflare Workers ```sh diff --git a/Taskfile.yaml b/Taskfile.yaml index d2a5befc..53978939 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -8,6 +8,7 @@ tasks: - test_no_rt - test_rt_tokio - test_rt_async-std + - test_rt_smol - test_rt_glommio - test_rt_worker @@ -16,6 +17,7 @@ tasks: - check_no_rt - check_rt_tokio - check_rt_async-std + - check_rt_smol - check_rt_glommio - check_rt_worker @@ -24,6 +26,7 @@ tasks: - cd benches && cargo bench --features DEBUG --no-run - cd benches && cargo check - cd benches_glommio && cargo check + - cd benches_smol && cargo check bench: dir: benches @@ -75,6 +78,15 @@ tasks: - cargo test --lib --features rt_async-std,DEBUG,{{.MAYBE_NIGHTLY}} - cargo test --lib --features rt_async-std,DEBUG,sse,ws,{{.MAYBE_NIGHTLY}} + test_rt_smol: + vars: + MAYBE_NIGHTLY: + sh: cargo version | grep -q 'nightly' && echo 'nightly' || echo '' + dir: ohkami + cmds: + - cargo test --lib --features rt_smol,DEBUG,{{.MAYBE_NIGHTLY}} + - cargo test --lib --features rt_smol,DEBUG,sse,ws,{{.MAYBE_NIGHTLY}} + test_rt_glommio: vars: MAYBE_NIGHTLY: @@ -131,6 +143,17 @@ tasks: - cargo check --lib --features rt_async-std,sse,{{.MAYBE_NIGHTLY}} - cargo check --lib --features rt_async-std,sse,ws,{{.MAYBE_NIGHTLY}} + check_rt_smol: + vars: + MAYBE_NIGHTLY: + sh: cargo version | grep -q 'nightly' && echo 'nightly' || echo '' + dir: ohkami + cmds: + - cargo check --lib --features rt_smol,{{.MAYBE_NIGHTLY}} + - cargo check --lib --features rt_smol,ip,{{.MAYBE_NIGHTLY}} + - cargo check --lib --features rt_smol,sse,{{.MAYBE_NIGHTLY}} + - cargo check --lib --features rt_smol,sse,ws,{{.MAYBE_NIGHTLY}} + check_rt_glommio: vars: MAYBE_NIGHTLY: diff --git a/benches_smol/Cargo.toml b/benches_smol/Cargo.toml new file mode 100644 index 00000000..d4528d3e --- /dev/null +++ b/benches_smol/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "ohkami_benches-with-smol" +version = "0.0.0" +edition = "2021" +authors = ["kanarus "] + +[dependencies] +# set `default-features = false` to assure "DEBUG" feature be off even when DEBUGing `../ohkami` +ohkami = { path = "../ohkami", default-features = false, features = ["rt_smol"] } +smol = { version = "2" } diff --git a/benches_smol/src/bin/param.rs b/benches_smol/src/bin/param.rs new file mode 100644 index 00000000..ea89d986 --- /dev/null +++ b/benches_smol/src/bin/param.rs @@ -0,0 +1,16 @@ +use ohkami::prelude::*; + + +#[inline(always)] +async fn echo_id(id: String) -> String { + id +} + +fn main() { + smol::block_on({ + Ohkami::new(( + "/user/:id" + .GET(echo_id), + )).howl("0.0.0.0:3000") + }) +} diff --git a/ohkami/Cargo.toml b/ohkami/Cargo.toml index d37ce4fd..83a47a67 100644 --- a/ohkami/Cargo.toml +++ b/ohkami/Cargo.toml @@ -23,6 +23,7 @@ ohkami_macros = { version = "=0.8.0", path = "../ohkami_macros" } tokio = { version = "1", optional = true, features = ["net", "rt", "io-util", "sync", "time"] } async-std = { version = "1", optional = true } +smol = { version = "2", optional = true } glommio = { version = "0.9", optional = true } worker = { version = "0.3", optional = true } @@ -45,7 +46,8 @@ default = ["testing"] rt_tokio = ["__rt__", "__rt_native__", "dep:tokio"] rt_async-std = ["__rt__", "__rt_native__", "dep:async-std"] -rt_glommio = ["__rt__", "__rt_native__", "dep:glommio", "dep:num_cpus", "dep:futures-util"] +rt_smol = ["__rt__", "__rt_native__", "dep:smol", "dep:futures-util"] +rt_glommio = ["__rt__", "__rt_native__", "dep:glommio", "dep:futures-util", "dep:num_cpus"] rt_worker = ["__rt__", "dep:worker", "ohkami_macros/worker"] nightly = [] @@ -71,8 +73,9 @@ DEBUG = [ # "sse", # "ws", # "ip", -# "rt_tokio", +# #"rt_tokio", # #"rt_async-std", +# "rt_smol", # #"rt_glommio", # #"rt_worker", # "DEBUG", diff --git a/ohkami/src/lib.rs b/ohkami/src/lib.rs index 07cc5915..65a8d054 100644 --- a/ohkami/src/lib.rs +++ b/ohkami/src/lib.rs @@ -1,4 +1,4 @@ -#![doc(html_root_url = "https://docs.rs/ohkami/0.20.0/ohkami/")] +#![doc(html_root_url = "https://docs.rs/ohkami/0.20.0/ohkami")] /* Execute static tests for sample codes in README */ #![cfg_attr(feature="DEBUG", doc = include_str!("../../README.md"))] @@ -29,11 +29,15 @@ #[cfg(any( all(feature="rt_tokio", feature="rt_async-std"), - all(feature="rt_async-std", feature="rt_glommio"), - all(feature="rt_glommio", feature="rt_worker"), - all(feature="rt_worker", feature="rt_tokio"), + all(feature="rt_tokio", feature="rt_smol"), all(feature="rt_tokio", feature="rt_glommio"), + all(feature="rt_tokio", feature="rt_worker"), + all(feature="rt_async-std", feature="rt_smol"), + all(feature="rt_async-std", feature="rt_glommio"), all(feature="rt_async-std", feature="rt_worker"), + all(feature="rt_smol", feature="rt_glommio"), + all(feature="rt_smol", feature="rt_worker"), + all(feature="rt_glommio", feature="rt_worker"), ))] compile_error! {" Can't activate multiple `rt_*` features at once! "} @@ -72,13 +76,17 @@ mod __rt__ { pub(crate) use async_std::net::{TcpListener, TcpStream, ToSocketAddrs}; #[cfg(feature="rt_glommio")] pub(crate) use {glommio::net::{TcpListener, TcpStream}, std::net::ToSocketAddrs}; + #[cfg(feature="rt_smol")] + pub(crate) use smol::net::{TcpListener, TcpStream, AsyncToSocketAddrs as ToSocketAddrs}; #[cfg(feature="rt_tokio")] - pub(crate) use tokio::task; + pub(crate) use tokio::task::spawn; #[cfg(feature="rt_async-std")] - pub(crate) use async_std::task; + pub(crate) use async_std::task::spawn; #[cfg(feature="rt_glommio")] - pub(crate) use glommio::task; + pub(crate) use glommio::spawn_local as spawn; + #[cfg(feature="rt_smol")] + pub(crate) use smol::spawn; #[cfg(feature="rt_tokio")] pub(crate) use tokio::time::sleep; @@ -86,6 +94,10 @@ mod __rt__ { pub(crate) use async_std::task::sleep; #[cfg(feature="rt_glommio")] pub(crate) use glommio::timer::sleep; + #[cfg(feature="rt_smol")] + pub(crate) async fn sleep(duration: std::time::Duration) { + smol::Timer::after(duration).await; + } #[cfg(feature="rt_tokio")] pub(crate) use tokio::io::AsyncReadExt as AsyncReader; @@ -93,6 +105,8 @@ mod __rt__ { pub(crate) use async_std::io::ReadExt as AsyncReader; #[cfg(feature="rt_glommio")] pub(crate) use futures_util::AsyncReadExt as AsyncReader; + #[cfg(feature="rt_smol")] + pub(crate) use futures_util::AsyncReadExt as AsyncReader; #[cfg(feature="rt_tokio")] pub(crate) use tokio::io::AsyncWriteExt as AsyncWriter; @@ -100,6 +114,8 @@ mod __rt__ { pub(crate) use async_std::io::WriteExt as AsyncWriter; #[cfg(feature="rt_glommio")] pub(crate) use futures_util::AsyncWriteExt as AsyncWriter; + #[cfg(feature="rt_smol")] + pub(crate) use futures_util::AsyncWriteExt as AsyncWriter; } diff --git a/ohkami/src/ohkami/mod.rs b/ohkami/src/ohkami/mod.rs index da46d2f7..c1a5457d 100644 --- a/ohkami/src/ohkami/mod.rs +++ b/ohkami/src/ohkami/mod.rs @@ -236,6 +236,7 @@ impl Ohkami { /// /// - `tokio::net::ToSocketAddrs` if using `tokio` /// - `async_std::net::ToSocketAddrs` if using `async-std` + /// - `smol::net::AsyncToSocketAddrs` if using `smol` /// - `std::net::ToSocketAddrs` if using `glommio` /// /// *note* : Keep-Alive timeout is 42 seconds and this is not @@ -293,9 +294,9 @@ impl Ohkami { pub async fn howl(self, address: impl __rt__::ToSocketAddrs) { let router = Arc::new(self.into_router().into_radix()); - #[cfg(any(feature="rt_tokio",feature="rt_async-std"))] + #[cfg(any(feature="rt_tokio",feature="rt_async-std",feature="rt_smol"))] let listener = __rt__::TcpListener::bind(address).await.expect("Failed to bind TCP listener"); - #[cfg(feature="rt_glommio")] + #[cfg(any(feature="rt_glommio"))] let listener = __rt__::TcpListener::bind(address).expect("Failed to bind TCP listener"); #[cfg(feature="rt_tokio")] { @@ -303,7 +304,7 @@ impl Ohkami { let ctrl_c = tokio::signal::ctrl_c(); let (ctrl_c_tx, ctrl_c_rx) = tokio::sync::watch::channel(()); - __rt__::task::spawn(async { + __rt__::spawn(async { ctrl_c.await.expect("Something was wrong around Ctrl-C"); drop(ctrl_c_rx); }); @@ -326,7 +327,7 @@ impl Ohkami { ); let close_rx = close_rx.clone(); - __rt__::task::spawn(async { + __rt__::spawn(async { session.manage().await; drop(close_rx) }); @@ -351,7 +352,7 @@ impl Ohkami { #[cfg(feature="ip")] let Ok((connection, addr)) = listener.accept().await else {continue}; - __rt__::task::spawn({ + __rt__::spawn({ Session::new( router.clone(), connection, @@ -371,7 +372,7 @@ impl Ohkami { #[cfg(feature="ip")] let Ok(addr) = connection.peer_addr() else {continue}; - __rt__::task::spawn({ + __rt__::spawn({ Session::new( router.clone(), connection, @@ -388,7 +389,24 @@ impl Ohkami { #[cfg(feature="ip")] let Ok(addr) = connection.peer_addr() else {continue}; - glommio::spawn_local({ + __rt__::spawn({ + Session::new( + router.clone(), + connection, + #[cfg(feature="ip")] addr.ip() + ).manage() + }).detach(); + } + } + + #[cfg(feature="rt_smol")] { + loop { + #[cfg(not(feature="ip"))] + let Ok((connection, _)) = listener.accept().await else {continue}; + #[cfg(feature="ip")] + let Ok((connection, addr)) = listener.accept().await else {continue}; + + __rt__::spawn({ Session::new( router.clone(), connection, diff --git a/ohkami/src/ws/connection.rs b/ohkami/src/ws/connection.rs index e21b0d01..cedcb3d0 100644 --- a/ohkami/src/ws/connection.rs +++ b/ohkami/src/ws/connection.rs @@ -15,7 +15,6 @@ pub struct Connection { enum State { Alive, Closed } const _: () = { - #[cfg(any(feature="rt_tokio",feature="rt_async-std"))] unsafe impl Send for Connection {} impl std::fmt::Debug for Connection {