fix Async constructor cannot specify a timeout (rust.nim:416). new_async hardcodes Duration::from_secs(30) for all subsequent calls on the produced Ctx, while blocking create

accepts a timeout: Duration. Inconsistent and a footgun for any user who picks the async path. Add the parameter.
This commit is contained in:
Ivan FB 2026-05-11 21:23:24 +02:00
parent 24a56032af
commit 51ed83b04a
No known key found for this signature in database
GPG Key ID: DF0C67A04C543270
3 changed files with 12 additions and 8 deletions

View File

@ -114,14 +114,14 @@ impl NimTimerCtx {
Ok(Self { ptr: addr as *mut c_void, timeout })
}
pub async fn new_async(config: TimerConfig) -> Result<Self, String> {
pub async fn new_async(config: TimerConfig, timeout: Duration) -> Result<Self, String> {
let config_json = serde_json::to_string(&config).map_err(|e| e.to_string())?;
let config_c = CString::new(config_json).unwrap();
let raw = ffi_call_async(move |cb, ud| unsafe {
ffi::nimtimer_create(config_c.as_ptr(), cb, ud)
}).await?;
let addr: usize = raw.parse().map_err(|e: std::num::ParseIntError| e.to_string())?;
Ok(Self { ptr: addr as *mut c_void, timeout: Duration::from_secs(30) })
Ok(Self { ptr: addr as *mut c_void, timeout })
}
pub fn echo(&self, req: EchoRequest) -> Result<EchoResponse, String> {

View File

@ -1,8 +1,13 @@
use std::time::Duration;
use nimtimer::{EchoRequest, NimTimerCtx, TimerConfig};
#[tokio::main(flavor = "multi_thread", worker_threads = 2)]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let ctx = NimTimerCtx::new_async(TimerConfig { name: "tokio-demo".into() }).await?;
let ctx = NimTimerCtx::new_async(
TimerConfig { name: "tokio-demo".into() },
Duration::from_secs(30),
)
.await?;
let version = ctx.version_async().await?;
println!("[1] Tokio runtime started");

View File

@ -367,8 +367,7 @@ proc generateApiRs*(procs: seq[FFIProcMeta], libName: string): string =
asyncParamsList.add(
"$1: $2" % [toSnakeCase(ep.name), nimTypeToRust(ep.typeName)]
)
let asyncParamsStr = asyncParamsList.join(", ")
let blockingParamsStr =
let paramsStr =
if asyncParamsList.len > 0: asyncParamsList.join(", ") & ", timeout: Duration"
else: "timeout: Duration"
@ -396,7 +395,7 @@ proc generateApiRs*(procs: seq[FFIProcMeta], libName: string): string =
let ffiCallArgsStr = ffiCallArgs.join(", ")
# -- blocking create --
lines.add(" pub fn create($1) -> Result<Self, String> {" % [blockingParamsStr])
lines.add(" pub fn create($1) -> Result<Self, String> {" % [paramsStr])
for ep in ctor.extraParams:
emitSerialize(toSnakeCase(ep.name), nimTypeToRust(ep.typeName))
lines.add(" let raw = ffi_call(timeout, |cb, ud| unsafe {")
@ -409,14 +408,14 @@ proc generateApiRs*(procs: seq[FFIProcMeta], libName: string): string =
# -- async new_async --
# move closure: each CString is moved in (Send), no raw ptr escapes the block
lines.add(" pub async fn new_async($1) -> Result<Self, String> {" % [asyncParamsStr])
lines.add(" pub async fn new_async($1) -> Result<Self, String> {" % [paramsStr])
for ep in ctor.extraParams:
emitSerialize(toSnakeCase(ep.name), nimTypeToRust(ep.typeName))
lines.add(" let raw = ffi_call_async(move |cb, ud| unsafe {")
lines.add(" ffi::$1($2)" % [ctor.procName, ffiCallArgsStr])
lines.add(" }).await?;")
lines.add(" let addr: usize = raw.parse().map_err(|e: std::num::ParseIntError| e.to_string())?;")
lines.add(" Ok(Self { ptr: addr as *mut c_void, timeout: Duration::from_secs(30) })")
lines.add(" Ok(Self { ptr: addr as *mut c_void, timeout })")
lines.add(" }")
lines.add("")