Skip to main content

nros/guide/
services.rs

1//! # Service Calls and Promise API
2//!
3//! `client.call(&request)` returns a `Promise` immediately — no blocking.
4//! The reply is polled with `take()` while the executor spins.
5//!
6//! ## Sync polling (no async runtime)
7//!
8//! Drive I/O with `spin_once()` while polling the promise:
9//!
10//! ```ignore
11//! use nros::prelude::*;
12//! use example_interfaces::srv::{AddTwoInts, AddTwoIntsRequest};
13//!
14//! let config = ExecutorConfig::from_env().node_name("client");
15//! let mut executor: Executor = Executor::open(&config)?;
16//! let mut node = executor.create_node("client")?;
17//! let mut client = node.create_client::<AddTwoInts>("/add_two_ints")?;
18//!
19//! let mut promise = client.call(&AddTwoIntsRequest { a: 1, b: 2 })?;
20//!
21//! let reply = loop {
22//!     executor.spin_once(core::time::Duration::from_millis(10));
23//!     if let Ok(Some(reply)) = promise.take() {
24//!         break reply;
25//!     }
26//! };
27//! println!("sum = {}", reply.sum);
28//! ```
29//!
30//! A promise is also a `Future`, but nano-ros drives no foreign async runtime:
31//! an async task that waited on one with no spin running elsewhere would wait
32//! forever. RFC-0113 retired `spin_async` because a host's scheduler, not
33//! nano-ros, would decide when its callbacks run.