shape_runtime/
sync_bridge.rs1use shape_ast::error::{Result, ShapeError};
8use std::future::Future;
9use std::sync::{Arc, OnceLock};
10use tokio::runtime::{Handle, Runtime};
11
12static SHARED_RUNTIME: OnceLock<Arc<Runtime>> = OnceLock::new();
14
15pub fn initialize_shared_runtime() -> Result<()> {
17 if SHARED_RUNTIME.get().is_some() {
18 return Ok(()); }
20
21 let runtime = Runtime::new().map_err(|e| ShapeError::RuntimeError {
22 message: format!("Failed to create shared Tokio runtime: {}", e),
23 location: None,
24 })?;
25
26 SHARED_RUNTIME
27 .set(Arc::new(runtime))
28 .map_err(|_| ShapeError::RuntimeError {
29 message: "Failed to set shared runtime (race condition)".to_string(),
30 location: None,
31 })?;
32
33 Ok(())
34}
35
36pub fn get_runtime_handle() -> Result<Handle> {
38 let runtime = SHARED_RUNTIME
39 .get()
40 .ok_or_else(|| ShapeError::RuntimeError {
41 message: "Shared runtime not initialized. Call initialize_shared_runtime() first."
42 .to_string(),
43 location: None,
44 })?;
45
46 Ok(runtime.handle().clone())
47}
48
49pub fn block_on_shared<F, T>(future: F) -> Result<T>
54where
55 F: Future<Output = T> + Send + 'static,
56 T: Send + 'static,
57{
58 let handle = get_runtime_handle()?;
59
60 let result = if let Ok(_handle_in_runtime) = Handle::try_current() {
62 let (tx, rx) = std::sync::mpsc::channel();
64 handle.spawn(async move {
65 let result = future.await;
66 let _ = tx.send(result);
67 });
68 rx.recv().map_err(|e| ShapeError::RuntimeError {
69 message: format!("Failed to receive async result: {}", e),
70 location: None,
71 })?
72 } else {
73 handle.block_on(future)
75 };
76
77 Ok(result)
78}
79
80#[derive(Clone)]
85pub struct SyncDataProvider {
86 _placeholder: std::marker::PhantomData<()>,
87}