metrale_bench/benchmarks/scheduler_equivalence/
host.rs1use std::collections::BTreeMap;
11use std::sync::Arc;
12
13use anyhow::Result;
14use futures::future::BoxFuture;
15use parking_lot::RwLock;
16
17use crate::plugin::TargetEndpoint;
18
19#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
21pub enum Router {
22 Sync,
23 Async,
24}
25
26impl Router {
27 pub fn flag_value(self) -> &'static str {
28 match self {
29 Router::Sync => "sync",
30 Router::Async => "async",
31 }
32 }
33}
34
35#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
37pub enum Lane {
38 SpecOff,
40 MtpForce,
43}
44
45impl Lane {
46 pub fn label(self) -> &'static str {
47 match self {
48 Lane::SpecOff => "spec-off",
49 Lane::MtpForce => "mtp-force",
50 }
51 }
52}
53
54#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
56pub struct ServeVariant {
57 pub router: Router,
58 pub lane: Lane,
59}
60
61impl ServeVariant {
62 pub fn label(self) -> String {
63 format!("{}/{}", self.router.flag_value(), self.lane.label())
64 }
65}
66
67pub trait RouterHost: Send + Sync {
70 fn serve(&self, variant: ServeVariant) -> BoxFuture<'_, Result<TargetEndpoint>>;
73
74 fn diagnostics(&self) -> Result<BTreeMap<String, f64>>;
78
79 fn restore(&self) -> BoxFuture<'_, Result<()>>;
82}
83
84static HOST: RwLock<Option<Arc<dyn RouterHost>>> = RwLock::new(None);
88
89pub fn install(host: Arc<dyn RouterHost>) {
92 *HOST.write() = Some(host);
93}
94
95pub fn installed() -> Option<Arc<dyn RouterHost>> {
96 HOST.read().clone()
97}
98
99pub const NO_HOST: &str = "the scheduler-equivalence gate needs the Metrale Engine server that \
101 serves the checkpoint: it re-serves the model under each router itself. Run it from the \
102 dashboard's Benchmarks pane, or headless with `met bench run scheduler-equivalence \
103 --pull-request-gate`, which starts the server in this process. Pointing it at a foreign \
104 endpoint with --url cannot work: the endpoint would stay on one router.";