Skip to main content

managed_client/
managed_client.rs

1//! Managed multi-target client example (`tokio` feature).
2//!
3//! [`BlockingManagedClient`] runs one or more targets under a dedicated
4//! current-thread Tokio runtime and exposes a synchronous handle, so a caller
5//! that does not want to touch Tokio directly can still get managed
6//! multi-target orchestration, retries, and a lossy event stream.
7//!
8//! Run a server first, then run this example:
9//!
10//! ```text
11//! cargo run -p irtt-rs --bin irtt-server --features server
12//! cargo run -p irtt-client --example managed_client --features tokio
13//! ```
14//!
15//! This example does not wait for the managed run to finish naturally: it
16//! requests a stop after a fixed short window so it exits promptly even
17//! without a reachable server.
18
19use std::time::Duration;
20
21use irtt_client::managed::{
22    BlockingManagedClient, ManagedClientConfig, ManagedCompletionPolicy, ManagedEvent,
23    ManagedTargetConfig,
24};
25use irtt_client::{ClientConfig, OpenPolicy, SessionRequest};
26
27fn main() {
28    let config = ManagedClientConfig {
29        client: ClientConfig {
30            open: OpenPolicy {
31                timeouts: vec![Duration::from_millis(300)],
32                ..Default::default()
33            },
34            request: SessionRequest {
35                duration: None,
36                interval: Duration::from_millis(200),
37                ..Default::default()
38            },
39            ..Default::default()
40        },
41        completion: ManagedCompletionPolicy::ExplicitStop,
42        ..Default::default()
43    };
44    let targets = vec![ManagedTargetConfig::new("local", "127.0.0.1:2112")];
45
46    let (owner, mut events) = match BlockingManagedClient::start_with_subscription(config, targets)
47    {
48        Ok(started) => started,
49        Err(err) => {
50            eprintln!("failed to start managed client: {err}");
51            return;
52        }
53    };
54
55    let stop_after = Duration::from_secs(1);
56    let deadline = std::time::Instant::now() + stop_after;
57    while std::time::Instant::now() < deadline {
58        match events.try_recv() {
59            Ok(event) => print_event(&event),
60            Err(_) => std::thread::sleep(Duration::from_millis(50)),
61        }
62    }
63
64    // `stop()` requests the stop synchronously; the returned receipt is only
65    // useful for awaiting durable acknowledgement, which this blocking
66    // example does not need.
67    std::mem::drop(owner.handle().stop());
68    match owner.join() {
69        Ok(outcome) => println!("managed run ended: {:?}", outcome.end_reason),
70        Err(err) => eprintln!("managed worker did not join cleanly: {err}"),
71    }
72}
73
74fn print_event(event: &ManagedEvent) {
75    match event {
76        ManagedEvent::Client { target, event } => println!("{}: {event:?}", target.id),
77        other => println!("{other:?}"),
78    }
79}