Skip to main content

robot_bus/
worker_thread.rs

1//! Background worker runner for tests and simple deployments.
2
3use std::sync::Arc;
4use std::sync::atomic::{AtomicBool, Ordering};
5use std::thread::{self, JoinHandle};
6
7use crate::action_bus::{ActionGoalHandler, ActionWorker};
8use crate::errors::Result;
9use crate::service_bus::{ServiceHandler, ServiceWorker};
10
11pub struct WorkerThread {
12    stop: Arc<AtomicBool>,
13    handle: JoinHandle<()>,
14}
15
16impl WorkerThread {
17    pub fn spawn_service(
18        service_name: impl Into<String>,
19        handler: ServiceHandler,
20        endpoint: impl Into<String>,
21    ) -> Result<Self> {
22        let service_name = service_name.into();
23        let endpoint = endpoint.into();
24        let stop = Arc::new(AtomicBool::new(false));
25        let stop_flag = stop.clone();
26        let handle = thread::spawn(move || {
27            let mut worker =
28                match ServiceWorker::new(service_name, handler, Some(&endpoint), None, 2500) {
29                    Ok(worker) => worker,
30                    Err(err) => {
31                        log::error!("service worker startup failed: {err}");
32                        return;
33                    }
34                };
35            while !stop_flag.load(Ordering::Relaxed) {
36                let _ = worker.serve_once(500);
37            }
38            worker.close();
39        });
40        Ok(Self { stop, handle })
41    }
42
43    pub fn spawn_action(
44        action_name: impl Into<String>,
45        handler: ActionGoalHandler,
46        endpoint: impl Into<String>,
47    ) -> Result<Self> {
48        let action_name = action_name.into();
49        let endpoint = endpoint.into();
50        let stop = Arc::new(AtomicBool::new(false));
51        let stop_flag = stop.clone();
52        let handle = thread::spawn(move || {
53            let mut worker =
54                match ActionWorker::new(action_name, handler, Some(&endpoint), None, 2500) {
55                    Ok(worker) => worker,
56                    Err(err) => {
57                        log::error!("action worker startup failed: {err}");
58                        return;
59                    }
60                };
61            while !stop_flag.load(Ordering::Relaxed) {
62                let _ = worker.serve_once(500);
63            }
64            worker.close();
65        });
66        Ok(Self { stop, handle })
67    }
68
69    pub fn stop(self) {
70        self.stop.store(true, Ordering::Relaxed);
71        let _ = self.handle.join();
72    }
73}