xref: /aosp_15_r20/external/crosvm/metrics/src/controller.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker //! Encapsulate the main runtime loop of a metrics process.
6*bb4ee6a4SAndroid Build Coastguard Worker 
7*bb4ee6a4SAndroid Build Coastguard Worker use anyhow::Result;
8*bb4ee6a4SAndroid Build Coastguard Worker use base::info;
9*bb4ee6a4SAndroid Build Coastguard Worker use base::EventToken;
10*bb4ee6a4SAndroid Build Coastguard Worker use base::RecvTube;
11*bb4ee6a4SAndroid Build Coastguard Worker 
12*bb4ee6a4SAndroid Build Coastguard Worker use crate::RequestHandler;
13*bb4ee6a4SAndroid Build Coastguard Worker 
14*bb4ee6a4SAndroid Build Coastguard Worker /// Runs the metrics controller.
15*bb4ee6a4SAndroid Build Coastguard Worker pub struct MetricsController {
16*bb4ee6a4SAndroid Build Coastguard Worker     pub(crate) agents: Vec<RecvTube>,
17*bb4ee6a4SAndroid Build Coastguard Worker     handler: RequestHandler,
18*bb4ee6a4SAndroid Build Coastguard Worker     pub(crate) closed_tubes: usize,
19*bb4ee6a4SAndroid Build Coastguard Worker }
20*bb4ee6a4SAndroid Build Coastguard Worker 
21*bb4ee6a4SAndroid Build Coastguard Worker #[derive(EventToken)]
22*bb4ee6a4SAndroid Build Coastguard Worker pub(crate) enum MetricsControllerToken {
23*bb4ee6a4SAndroid Build Coastguard Worker     /// Triggered when the agent's pipe is readable (e.g. read_notifier).
24*bb4ee6a4SAndroid Build Coastguard Worker     Agent(usize),
25*bb4ee6a4SAndroid Build Coastguard Worker     /// Triggered when the agent's pipe closes (e.g. close_notifier).
26*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(windows)]
27*bb4ee6a4SAndroid Build Coastguard Worker     AgentExited(usize),
28*bb4ee6a4SAndroid Build Coastguard Worker }
29*bb4ee6a4SAndroid Build Coastguard Worker 
30*bb4ee6a4SAndroid Build Coastguard Worker impl MetricsController {
new(agents: Vec<RecvTube>) -> Self31*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new(agents: Vec<RecvTube>) -> Self {
32*bb4ee6a4SAndroid Build Coastguard Worker         Self {
33*bb4ee6a4SAndroid Build Coastguard Worker             agents,
34*bb4ee6a4SAndroid Build Coastguard Worker             handler: RequestHandler::new(),
35*bb4ee6a4SAndroid Build Coastguard Worker             closed_tubes: 0,
36*bb4ee6a4SAndroid Build Coastguard Worker         }
37*bb4ee6a4SAndroid Build Coastguard Worker     }
38*bb4ee6a4SAndroid Build Coastguard Worker 
39*bb4ee6a4SAndroid Build Coastguard Worker     /// Run the metrics controller until all clients exit & close their Tubes.
run(&mut self) -> Result<()>40*bb4ee6a4SAndroid Build Coastguard Worker     pub fn run(&mut self) -> Result<()> {
41*bb4ee6a4SAndroid Build Coastguard Worker         self.run_internal()?;
42*bb4ee6a4SAndroid Build Coastguard Worker         self.handler.shutdown();
43*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
44*bb4ee6a4SAndroid Build Coastguard Worker     }
45*bb4ee6a4SAndroid Build Coastguard Worker 
46*bb4ee6a4SAndroid Build Coastguard Worker     /// Handles a tube that has indicated it has data ready to read.
on_tube_readable(&self, client: &RecvTube)47*bb4ee6a4SAndroid Build Coastguard Worker     pub(crate) fn on_tube_readable(&self, client: &RecvTube) {
48*bb4ee6a4SAndroid Build Coastguard Worker         self.handler.handle_tube_readable(client)
49*bb4ee6a4SAndroid Build Coastguard Worker     }
50*bb4ee6a4SAndroid Build Coastguard Worker 
51*bb4ee6a4SAndroid Build Coastguard Worker     /// Handles a closed connection, and returns a bool indicating
52*bb4ee6a4SAndroid Build Coastguard Worker     /// whether the run loop itself should close.
on_connection_closed(&mut self) -> bool53*bb4ee6a4SAndroid Build Coastguard Worker     pub(crate) fn on_connection_closed(&mut self) -> bool {
54*bb4ee6a4SAndroid Build Coastguard Worker         self.closed_tubes += 1;
55*bb4ee6a4SAndroid Build Coastguard Worker         info!(
56*bb4ee6a4SAndroid Build Coastguard Worker             "metrics tube closed: {} out of {} closed",
57*bb4ee6a4SAndroid Build Coastguard Worker             self.closed_tubes,
58*bb4ee6a4SAndroid Build Coastguard Worker             self.agents.len(),
59*bb4ee6a4SAndroid Build Coastguard Worker         );
60*bb4ee6a4SAndroid Build Coastguard Worker         if self.closed_tubes == self.agents.len() {
61*bb4ee6a4SAndroid Build Coastguard Worker             info!("metrics run loop exiting: all tubes closed");
62*bb4ee6a4SAndroid Build Coastguard Worker             return true;
63*bb4ee6a4SAndroid Build Coastguard Worker         }
64*bb4ee6a4SAndroid Build Coastguard Worker 
65*bb4ee6a4SAndroid Build Coastguard Worker         false
66*bb4ee6a4SAndroid Build Coastguard Worker     }
67*bb4ee6a4SAndroid Build Coastguard Worker }
68