metrale_scheduler/
types.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! 2026-09-25: Small value types shared by the routers.
4//!
5//! Owner: scheduler.
6//! Invariants: none beyond the types.
7
8use std::time::Duration;
9
10/// 2026-09-25: A launched step, to be settled with `DeviceIo::await_result`.
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub struct Ticket(pub u32);
13
14/// 2026-09-25: How long a request router's `recv` may wait for something to arrive.
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum WaitPolicy {
17    /// 2026-09-25: Return whatever is queued, at once.
18    NoWait,
19    /// 2026-09-25: Wait at most this long for a request, a rotation or the close.
20    Bounded(Duration),
21    /// 2026-09-25: Wait until a request or a rotation is queued, or the inbox closes.
22    Block,
23}
24
25/// 2026-09-25: The KV pool and SSM snapshot counters a router reports.
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub struct DeviceFacts {
28    pub free_blocks: usize,
29    pub total_blocks: usize,
30    pub ssm_occupancy: Option<(u32, u32)>,
31}
32
33/// 2026-09-25: A device failure, split by when it happened: the forward itself (the
34/// batch may be preemptible), the readback after it, or an effect.
35#[derive(Debug)]
36pub enum DeviceError {
37    Forward(anyhow::Error),
38    Readback(anyhow::Error),
39    Effect(anyhow::Error),
40}
41
42impl DeviceError {
43    pub fn into_inner(self) -> anyhow::Error {
44        match self {
45            Self::Forward(e) | Self::Readback(e) | Self::Effect(e) => e,
46        }
47    }
48
49    /// 2026-09-25: A forward error whose message reports KV cache exhaustion (the pool
50    /// ran dry mid-batch).
51    pub fn is_kv_exhausted(&self) -> bool {
52        matches!(self, Self::Forward(e) if format!("{e:#}").contains("KV cache exhausted"))
53    }
54}
55
56impl std::fmt::Display for DeviceError {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        match self {
59            Self::Forward(e) | Self::Readback(e) | Self::Effect(e) => write!(f, "{e:#}"),
60        }
61    }
62}