use crate::connection::path::PathMap;
use crate::connection::space::PacketNumSpaceMap;
use crate::connection::stream::StreamMap;
use crate::multipath_scheduler::MultipathScheduler;
use crate::Error;
use crate::MultipathConfig;
use crate::Result;
pub struct MinRttScheduler {}
impl MinRttScheduler {
pub fn new(_conf: &MultipathConfig) -> MinRttScheduler {
MinRttScheduler {}
}
}
impl MultipathScheduler for MinRttScheduler {
fn on_select(
&mut self,
paths: &mut PathMap,
spaces: &mut PacketNumSpaceMap,
streams: &mut StreamMap,
) -> Result<usize> {
let mut best = None;
for (pid, path) in paths.iter_mut() {
if !path.active() || !path.recovery.can_send() {
continue;
}
let srtt = path.recovery.rtt.smoothed_rtt();
match best {
None => best = Some((pid, srtt)),
Some((_, rtt)) => {
if srtt < rtt {
best = Some((pid, srtt));
}
}
}
}
match best {
Some((i, _)) => Ok(i),
None => Err(Error::Done),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::multipath_scheduler::tests::*;
#[test]
fn minrtt_single_available_path() -> Result<()> {
let mut t = MultipathTester::new()?;
let mut s = MinRttScheduler {};
assert_eq!(s.on_select(&mut t.paths, &mut t.spaces, &mut t.streams)?, 0);
assert_eq!(s.on_select(&mut t.paths, &mut t.spaces, &mut t.streams)?, 0);
Ok(())
}
#[test]
fn minrtt_multi_available_path() -> Result<()> {
let mut t = MultipathTester::new()?;
t.add_path("127.0.0.1:443", "127.0.0.2:8443", 50)?;
t.add_path("127.0.0.1:443", "127.0.0.3:8443", 150)?;
t.add_path("127.0.0.1:443", "127.0.0.4:8443", 100)?;
let mut s = MinRttScheduler {};
assert_eq!(s.on_select(&mut t.paths, &mut t.spaces, &mut t.streams)?, 1);
t.set_path_active(1, false)?;
assert_eq!(s.on_select(&mut t.paths, &mut t.spaces, &mut t.streams)?, 3);
Ok(())
}
#[test]
fn minrtt_no_available_path() -> Result<()> {
let mut t = MultipathTester::new()?;
t.set_path_active(0, false)?;
let mut s = MinRttScheduler {};
assert_eq!(
s.on_select(&mut t.paths, &mut t.spaces, &mut t.streams),
Err(Error::Done)
);
Ok(())
}
}