solana_core/
stats_reporter_service.rs

1use {
2    crossbeam_channel::{Receiver, RecvTimeoutError},
3    std::{
4        result::Result,
5        sync::{
6            atomic::{AtomicBool, Ordering},
7            Arc,
8        },
9        thread::{self, Builder, JoinHandle},
10        time::Duration,
11    },
12};
13
14pub struct StatsReporterService {
15    thread_hdl: JoinHandle<()>,
16}
17
18impl StatsReporterService {
19    pub fn new(
20        reporting_receiver: Receiver<Box<dyn FnOnce() + Send>>,
21        exit: Arc<AtomicBool>,
22    ) -> Self {
23        let thread_hdl = Builder::new()
24            .name("solStatsReport".to_owned())
25            .spawn(move || loop {
26                if exit.load(Ordering::Relaxed) {
27                    return;
28                }
29                if let Err(e) = Self::receive_reporting_func(&reporting_receiver) {
30                    match e {
31                        RecvTimeoutError::Disconnected => break,
32                        RecvTimeoutError::Timeout => (),
33                    }
34                }
35            })
36            .unwrap();
37
38        Self { thread_hdl }
39    }
40
41    pub fn join(self) -> thread::Result<()> {
42        self.thread_hdl.join()?;
43        Ok(())
44    }
45
46    fn receive_reporting_func(
47        r: &Receiver<Box<dyn FnOnce() + Send>>,
48    ) -> Result<(), RecvTimeoutError> {
49        let timer = Duration::new(1, 0);
50        let func = r.recv_timeout(timer)?;
51        func();
52        Ok(())
53    }
54}