use log::debug;
use rand::Rng;
use crate::load_balancer::instances::InstanceMetrics;
pub trait LoadBalancingStrategy {
fn select_instance(&mut self, metrics: &[InstanceMetrics]) -> usize;
}
pub struct LeastRecentlyUsedStrategy;
impl LeastRecentlyUsedStrategy {
pub fn new() -> Self {
Self {}
}
}
impl LoadBalancingStrategy for LeastRecentlyUsedStrategy {
fn select_instance(&mut self, metrics: &[InstanceMetrics]) -> usize {
if metrics.is_empty() {
panic!("LoadBalancingStrategy::select_instance called with empty metrics slice");
}
let mut oldest_index = 0;
let mut oldest_time = metrics[0].last_used;
for (i, metric) in metrics.iter().enumerate().skip(1) {
if metric.last_used < oldest_time {
oldest_index = i;
oldest_time = metric.last_used;
}
}
debug!(
"LeastRecentlyUsedStrategy: Selected index {} (ID: {}) from {} eligible metrics with last_used: {:?}",
oldest_index, metrics[oldest_index].id, metrics.len(), oldest_time
);
oldest_index
}
}
#[derive(Debug, Default)]
pub struct LowestLatencyStrategy;
impl LowestLatencyStrategy {
pub fn new() -> Self {
Self {}
}
}
impl LoadBalancingStrategy for LowestLatencyStrategy {
fn select_instance(&mut self, metrics: &[InstanceMetrics]) -> usize {
if metrics.is_empty() {
panic!("LowestLatencyStrategy::select_instance called with empty metrics slice");
}
let mut best_index = 0;
let mut lowest_time = metrics[0].avg_response_time;
for (i, metric) in metrics.iter().enumerate().skip(1) {
if metric.avg_response_time < lowest_time {
best_index = i;
lowest_time = metric.avg_response_time;
}
}
debug!(
"LowestLatencyStrategy: Selected index {} (ID: {}) from {} eligible metrics with avg_response_time: {:?}",
best_index, metrics[best_index].id, metrics.len(), lowest_time
);
best_index
}
}
#[derive(Debug, Default)]
pub struct RandomStrategy;
impl RandomStrategy {
pub fn new() -> Self {
Self {}
}
}
impl LoadBalancingStrategy for RandomStrategy {
fn select_instance(&mut self, metrics: &[InstanceMetrics]) -> usize {
if metrics.is_empty() {
panic!("RandomStrategy::select_instance called with empty metrics slice");
}
let index = rand::rng().random_range(0..metrics.len());
debug!(
"RandomStrategy: Selected random index {} (ID: {}) from {} eligible metrics",
index, metrics[index].id, metrics.len()
);
index
}
}