rust_webx_core/
dispatch_runtime.rs1use std::future::Future;
9use std::sync::Arc;
10
11use crate::route::scan::{try_global_provider, HandlerCache};
12
13tokio::task_local! {
14 static ACTIVE_RUNTIME: Option<Arc<DispatchRuntime>>;
15}
16
17#[derive(Clone)]
19pub struct DispatchRuntime {
20 provider: Arc<rust_dix::ServiceProvider>,
21 handler_cache: Arc<HandlerCache>,
22}
23
24impl DispatchRuntime {
25 pub fn new(provider: Arc<rust_dix::ServiceProvider>, handler_cache: Arc<HandlerCache>) -> Self {
26 Self {
27 provider,
28 handler_cache,
29 }
30 }
31
32 pub fn provider(&self) -> &Arc<rust_dix::ServiceProvider> {
33 &self.provider
34 }
35
36 pub fn handler_cache(&self) -> &Arc<HandlerCache> {
37 &self.handler_cache
38 }
39
40 pub async fn run<F, R>(&self, f: F) -> R
42 where
43 F: Future<Output = R>,
44 {
45 ACTIVE_RUNTIME
46 .scope(Some(Arc::new(self.clone())), f)
47 .await
48 }
49}
50
51pub fn dispatch_provider() -> Arc<rust_dix::ServiceProvider> {
57 if let Ok(runtime_provider) = ACTIVE_RUNTIME.try_with(|rt| {
58 rt.as_ref().map(|r| Arc::clone(&r.provider))
59 }) {
60 if let Some(provider) = runtime_provider {
61 return provider;
62 }
63 }
64
65 if let Some(provider) = try_global_provider() {
66 tracing::warn!(
67 "dispatch_provider() using deprecated global ServiceProvider shim; \
68 prefer Host::dispatch_runtime().run() or host.provider()"
69 );
70 return provider;
71 }
72
73 panic!(
74 "No active DispatchRuntime and no deprecated global ServiceProvider. \
75 HTTP and hosted services run inside Host::dispatch_runtime().run(); \
76 for tests use host.dispatch_runtime().run with an async block, or host.provider()."
77 );
78}
79
80pub fn dispatch_handler_cache() -> Arc<HandlerCache> {
85 if let Ok(runtime_cache) = ACTIVE_RUNTIME.try_with(|rt| {
86 rt.as_ref().map(|r| Arc::clone(&r.handler_cache))
87 }) {
88 if let Some(cache) = runtime_cache {
89 return cache;
90 }
91 }
92
93 #[allow(deprecated)]
94 {
95 HandlerCache::get_or_init()
96 }
97}