use std::sync::Arc;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum RunnerType {
Subprocess,
Container,
Wasm,
}
impl RunnerType {
#[inline]
pub fn as_label(self) -> &'static str {
match self {
Self::Subprocess => "subprocess",
Self::Container => "container",
Self::Wasm => "wasm",
}
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RunnerErrorKind {
CgroupPrepareFailed,
BackendConfigFailed,
SpawnFailed,
ModuleLoadFailed,
}
impl RunnerErrorKind {
#[inline]
pub fn as_label(self) -> &'static str {
match self {
Self::CgroupPrepareFailed => "cgroup_prepare_failed",
Self::BackendConfigFailed => "backend_config_failed",
Self::SpawnFailed => "spawn_failed",
Self::ModuleLoadFailed => "module_load_failed",
}
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TaskOutcome {
Success,
Failure,
Canceled,
Timeout,
}
impl TaskOutcome {
#[inline]
pub fn as_label(&self) -> &'static str {
match self {
TaskOutcome::Success => "success",
TaskOutcome::Failure => "failure",
TaskOutcome::Canceled => "canceled",
TaskOutcome::Timeout => "timeout",
}
}
}
pub trait MetricsBackend: Send + Sync + 'static {
fn record_task_started(&self, runner_type: RunnerType);
fn record_task_completed(
&self,
runner_type: RunnerType,
outcome: TaskOutcome,
duration_ms: u64,
);
fn record_runner_error(&self, runner_type: RunnerType, error_kind: RunnerErrorKind);
}
pub type MetricsHandle = Arc<dyn MetricsBackend>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn runner_error_kind_as_label_maps_all_variants() {
assert_eq!(
RunnerErrorKind::CgroupPrepareFailed.as_label(),
"cgroup_prepare_failed"
);
assert_eq!(
RunnerErrorKind::BackendConfigFailed.as_label(),
"backend_config_failed"
);
assert_eq!(RunnerErrorKind::SpawnFailed.as_label(), "spawn_failed");
assert_eq!(
RunnerErrorKind::ModuleLoadFailed.as_label(),
"module_load_failed"
);
}
}