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)
@@ -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 {