use super::policy::{ResourcePolicy, WorkProfile};
use super::supervisor::ComputeSupervisor;
use super::telemetry::TelemetryEngine;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PlacementMode {
LocalFirst,
Spread,
Affinity {
node: String,
},
}
#[derive(Debug, Clone, PartialEq)]
pub struct ClusterResourcePolicy {
pub global: ResourcePolicy,
pub per_node: ResourcePolicy,
pub placement: PlacementMode,
}
impl ClusterResourcePolicy {
pub fn local_first(policy: ResourcePolicy) -> Self {
Self {
global: policy.clone(),
per_node: policy,
placement: PlacementMode::LocalFirst,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FabricJobSpec {
pub name: String,
pub payload: Vec<u8>,
pub work_profile: WorkProfile,
}
impl<E: TelemetryEngine> ComputeSupervisor<E> {
pub fn scale_out(
&self,
name: impl Into<String>,
payload: Vec<u8>,
profile: WorkProfile,
) -> FabricJobSpec {
FabricJobSpec {
name: name.into(),
payload,
work_profile: profile,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::compute::{AdmissionController, MockTelemetry};
#[test]
fn scale_out_returns_fabric_job_spec() {
let telemetry = MockTelemetry::new(0.9, 0.9);
let admission = std::sync::Arc::new(AdmissionController::new(1, 4));
let policy = ResourcePolicy::memory_cap_max_cpu(0.85);
let sup = ComputeSupervisor::new(policy, telemetry, admission);
let job = sup.scale_out(
"remote-work",
b"payload".to_vec(),
WorkProfile::CpuIntensive,
);
assert_eq!(job.name, "remote-work");
assert_eq!(job.work_profile, WorkProfile::CpuIntensive);
assert_eq!(job.payload, b"payload");
}
#[test]
fn local_first_policy_clones_caps() {
let policy = ResourcePolicy::memory_cap_max_cpu(0.85);
let cluster = ClusterResourcePolicy::local_first(policy.clone());
assert_eq!(cluster.global, policy);
assert_eq!(cluster.per_node, policy);
assert_eq!(cluster.placement, PlacementMode::LocalFirst);
}
}