diff --git a/examples/nim_timer/rust_bindings/Cargo.toml b/examples/nim_timer/rust_bindings/Cargo.toml index 68ef056..40596c0 100644 --- a/examples/nim_timer/rust_bindings/Cargo.toml +++ b/examples/nim_timer/rust_bindings/Cargo.toml @@ -3,6 +3,11 @@ name = "nimtimer" version = "0.1.0" edition = "2021" +[features] +default = [] +tokio-runtime = ["tokio"] + [dependencies] serde = { version = "1", features = ["derive"] } serde_json = "1" +tokio = { version = "1", optional = true, features = ["rt-multi-thread", "macros"] } diff --git a/examples/nim_timer/rust_bindings/src/api.rs b/examples/nim_timer/rust_bindings/src/api.rs index 7aa056f..aaf440c 100644 --- a/examples/nim_timer/rust_bindings/src/api.rs +++ b/examples/nim_timer/rust_bindings/src/api.rs @@ -5,6 +5,8 @@ use std::time::Duration; use super::ffi; use super::types::*; +const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5); + #[derive(Default)] struct FfiCallbackResult { payload: Option>, @@ -74,6 +76,15 @@ impl NimTimerCtx { Ok(Self { ptr: addr as *mut c_void, timeout }) } + pub fn new(config: TimerConfig) -> Result { + Self::create(config, DEFAULT_TIMEOUT) + } + + #[cfg(feature = "tokio")] + pub async fn new_async(config: TimerConfig) -> Result { + tokio::task::block_in_place(move || Self::new(config)) + } + pub fn echo(&self, req: EchoRequest) -> Result { let req_json = serde_json::to_string(&req).map_err(|e| e.to_string())?; let req_c = CString::new(req_json).unwrap(); @@ -90,6 +101,16 @@ impl NimTimerCtx { serde_json::from_str::(&raw).map_err(|e| e.to_string()) } + #[cfg(feature = "tokio")] + pub async fn version_async(&self) -> Result { + let ptr = self.ptr; + let timeout = self.timeout; + tokio::task::block_in_place(move || { + let ctx = Self { ptr, timeout }; + ctx.version() + }) + } + pub fn complex(&self, req: ComplexRequest) -> Result { let req_json = serde_json::to_string(&req).map_err(|e| e.to_string())?; let req_c = CString::new(req_json).unwrap(); @@ -99,4 +120,23 @@ impl NimTimerCtx { serde_json::from_str::(&raw).map_err(|e| e.to_string()) } + #[cfg(feature = "tokio")] + pub async fn echo_async(&self, req: EchoRequest) -> Result { + let ptr = self.ptr; + let timeout = self.timeout; + tokio::task::block_in_place(move || { + let ctx = Self { ptr, timeout }; + ctx.echo(req) + }) + } + + #[cfg(feature = "tokio")] + pub async fn complex_async(&self, req: ComplexRequest) -> Result { + let ptr = self.ptr; + let timeout = self.timeout; + tokio::task::block_in_place(move || { + let ctx = Self { ptr, timeout }; + ctx.complex(req) + }) + } } diff --git a/examples/nim_timer/rust_client/Cargo.lock b/examples/nim_timer/rust_client/Cargo.lock index 5c3459e..5bbc31e 100644 --- a/examples/nim_timer/rust_client/Cargo.lock +++ b/examples/nim_timer/rust_client/Cargo.lock @@ -20,6 +20,7 @@ version = "0.1.0" dependencies = [ "serde", "serde_json", + "tokio", ] [[package]] diff --git a/examples/nim_timer/rust_client/Cargo.toml b/examples/nim_timer/rust_client/Cargo.toml index cd21745..d28fdeb 100644 --- a/examples/nim_timer/rust_client/Cargo.toml +++ b/examples/nim_timer/rust_client/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -nimtimer = { path = "../rust_bindings" } +nimtimer = { path = "../rust_bindings", features = ["tokio-runtime"] } serde_json = "1" tokio = { version = "1", features = ["rt-multi-thread", "macros"] } diff --git a/examples/nim_timer/rust_client/src/tokio_main.rs b/examples/nim_timer/rust_client/src/tokio_main.rs index abb8934..5303de8 100644 --- a/examples/nim_timer/rust_client/src/tokio_main.rs +++ b/examples/nim_timer/rust_client/src/tokio_main.rs @@ -1,71 +1,30 @@ use nimtimer::{EchoRequest, NimTimerCtx, TimerConfig}; -use std::sync::{Arc, Mutex}; -use std::time::Duration; -use tokio::task; #[tokio::main(flavor = "multi_thread", worker_threads = 2)] -async fn main() { - let timeout = Duration::from_secs(5); - - let ctx = task::spawn_blocking(move || { - NimTimerCtx::create(TimerConfig { name: "tokio-demo".into() }, timeout) - }) - .await - .expect("failed to join create task") - .expect("nimtimer_create failed"); - - let ctx = Arc::new(Mutex::new(ctx)); - - let version = task::spawn_blocking({ - let ctx = Arc::clone(&ctx); - move || { - let ctx = ctx.lock().unwrap(); - ctx.version() - } - }) - .await - .expect("failed to join version task") - .expect("nimtimer_version failed"); +async fn main() -> Result<(), Box> { + let ctx = NimTimerCtx::new_async(TimerConfig { name: "tokio-demo".into() }).await?; + let version = ctx.version_async().await?; println!("[1] Tokio runtime started"); println!("[2] Version: {version}"); - let req1 = EchoRequest { - message: "hello from tokio".into(), - delay_ms: 200, - }; - let req2 = EchoRequest { - message: "second tokio request".into(), - delay_ms: 50, - }; + let echo1 = ctx + .echo_async(EchoRequest { + message: "hello from tokio".into(), + delay_ms: 200, + }) + .await?; - let fut1 = task::spawn_blocking({ - let ctx = Arc::clone(&ctx); - move || { - let ctx = ctx.lock().unwrap(); - ctx.echo(req1) - } - }); - - let fut2 = task::spawn_blocking({ - let ctx = Arc::clone(&ctx); - move || { - let ctx = ctx.lock().unwrap(); - ctx.echo(req2) - } - }); - - let echo1 = fut1 - .await - .expect("failed to join tokio blocking task") - .expect("nimtimer_echo failed"); - let echo2 = fut2 - .await - .expect("failed to join tokio blocking task") - .expect("nimtimer_echo failed"); + let echo2 = ctx + .echo_async(EchoRequest { + message: "second tokio request".into(), + delay_ms: 50, + }) + .await?; println!("[3] Echo 1: echoed={}, timerName={}", echo1.echoed, echo1.timer_name); println!("[4] Echo 2: echoed={}, timerName={}", echo2.echoed, echo2.timer_name); println!("\nDone. Tokio runtime shut down."); + Ok(()) }