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.scope(Some(Arc::new(self.clone())), f).await
46 }
47}
48
49pub fn dispatch_provider() -> Arc<rust_dix::ServiceProvider> {
55 if let Ok(Some(provider)) =
56 ACTIVE_RUNTIME.try_with(|rt| rt.as_ref().map(|r| Arc::clone(&r.provider)))
57 {
58 return provider;
59 }
60
61 if let Some(provider) = try_global_provider() {
62 tracing::warn!(
63 "dispatch_provider() using deprecated global ServiceProvider shim; \
64 prefer Host::dispatch_runtime().run() or host.provider()"
65 );
66 return provider;
67 }
68
69 panic!(
70 "No active DispatchRuntime and no deprecated global ServiceProvider. \
71 HTTP and hosted services run inside Host::dispatch_runtime().run(); \
72 for tests use host.dispatch_runtime().run with an async block, or host.provider()."
73 );
74}
75
76pub fn dispatch_handler_cache() -> Arc<HandlerCache> {
81 if let Ok(Some(cache)) =
82 ACTIVE_RUNTIME.try_with(|rt| rt.as_ref().map(|r| Arc::clone(&r.handler_cache)))
83 {
84 return cache;
85 }
86
87 #[allow(deprecated)]
88 {
89 HandlerCache::get_or_init()
90 }
91}