don't spawn a new runtime every request
This commit is contained in:
1 parent
cfd62e274e
commit
fcb993a2cb
2 files changed
+29
-22
No files matched your search
@@ -41,6 +41,7 @@ log = { workspace = true }
|
|||||||
once_cell = "1.17.1"
|
once_cell = "1.17.1"
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
tokio = { workspace = true, features = ["full"], optional = true }
|
tokio = { workspace = true, features = ["full"], optional = true }
|
||||||
|
tokio-util = { version = "0.7.8", features = ["rt"], optional = true }
|
||||||
object-pool = "0.5.4"
|
object-pool = "0.5.4"
|
||||||
anymap = "0.12.1"
|
anymap = "0.12.1"
|
||||||
|
|
||||||
@@ -68,7 +69,7 @@ hot-reload = ["serde_json", "futures-util"]
|
|||||||
warp = ["dep:warp", "ssr"]
|
warp = ["dep:warp", "ssr"]
|
||||||
axum = ["dep:axum", "tower-http", "ssr"]
|
axum = ["dep:axum", "tower-http", "ssr"]
|
||||||
salvo = ["dep:salvo", "ssr"]
|
salvo = ["dep:salvo", "ssr"]
|
||||||
ssr = ["server_fn/ssr", "tokio", "dioxus-ssr", "tower", "hyper", "http", "http-body", "dioxus-router/ssr", "tokio-stream"]
|
ssr = ["server_fn/ssr", "tokio", "tokio-util", "dioxus-ssr", "tower", "hyper", "http", "http-body", "dioxus-router/ssr", "tokio-stream"]
|
||||||
default-tls = ["server_fn/default-tls"]
|
default-tls = ["server_fn/default-tls"]
|
||||||
rustls = ["server_fn/rustls"]
|
rustls = ["server_fn/rustls"]
|
||||||
|
|
||||||
|
|||||||
@@ -17,12 +17,9 @@ pub mod salvo_adapter;
|
|||||||
#[cfg(feature = "warp")]
|
#[cfg(feature = "warp")]
|
||||||
pub mod warp_adapter;
|
pub mod warp_adapter;
|
||||||
|
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use http::StatusCode;
|
use http::StatusCode;
|
||||||
|
|
||||||
use server_fn::{Encoding, Payload};
|
use server_fn::{Encoding, Payload};
|
||||||
use tokio::task::spawn_blocking;
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
layer::{BoxedService, Service},
|
layer::{BoxedService, Service},
|
||||||
@@ -93,27 +90,22 @@ impl Service for ServerFnHandler {
|
|||||||
|
|
||||||
// Because the future returned by `server_fn_handler` is `Send`, and the future returned by this function must be send, we need to spawn a new runtime
|
// Because the future returned by `server_fn_handler` is `Send`, and the future returned by this function must be send, we need to spawn a new runtime
|
||||||
let (resp_tx, resp_rx) = tokio::sync::oneshot::channel();
|
let (resp_tx, resp_rx) = tokio::sync::oneshot::channel();
|
||||||
spawn_blocking({
|
let pool = get_local_pool();
|
||||||
|
pool.spawn_pinned({
|
||||||
let function = function.clone();
|
let function = function.clone();
|
||||||
let mut server_context = server_context.clone();
|
let mut server_context = server_context.clone();
|
||||||
server_context.parts = parts;
|
server_context.parts = parts;
|
||||||
move || {
|
move || async move {
|
||||||
tokio::runtime::Runtime::new()
|
let data = match function.encoding() {
|
||||||
.expect("couldn't spawn runtime")
|
Encoding::Url | Encoding::Cbor => &body,
|
||||||
.block_on(async move {
|
Encoding::GetJSON | Encoding::GetCBOR => &query,
|
||||||
let data = match function.encoding() {
|
};
|
||||||
Encoding::Url | Encoding::Cbor => &body,
|
let server_function_future = function.call((), data);
|
||||||
Encoding::GetJSON | Encoding::GetCBOR => &query,
|
let server_function_future =
|
||||||
};
|
ProvideServerContext::new(server_function_future, server_context.clone());
|
||||||
let server_function_future = function.call((), data);
|
let resp = server_function_future.await;
|
||||||
let server_function_future = ProvideServerContext::new(
|
|
||||||
server_function_future,
|
|
||||||
server_context.clone(),
|
|
||||||
);
|
|
||||||
let resp = server_function_future.await;
|
|
||||||
|
|
||||||
resp_tx.send(resp).unwrap();
|
resp_tx.send(resp).unwrap();
|
||||||
})
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let result = resp_rx.await.unwrap();
|
let result = resp_rx.await.unwrap();
|
||||||
@@ -158,3 +150,17 @@ impl Service for ServerFnHandler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_local_pool() -> tokio_util::task::LocalPoolHandle {
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
static LOCAL_POOL: OnceCell<tokio_util::task::LocalPoolHandle> = OnceCell::new();
|
||||||
|
LOCAL_POOL
|
||||||
|
.get_or_init(|| {
|
||||||
|
tokio_util::task::LocalPoolHandle::new(
|
||||||
|
std::thread::available_parallelism()
|
||||||
|
.map(Into::into)
|
||||||
|
.unwrap_or(1),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.clone()
|
||||||
|
}
|
||||||
Reference in new issue
Block a user