use crate::core::PacketKey;
use super::TimeoutEvent;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum RetransmitDecision {
Retransmit {
key: PacketKey,
},
Wait {
key: PacketKey,
},
Drop {
key: PacketKey,
},
}
pub trait RetransmitPolicy {
fn on_timeout(&mut self, event: TimeoutEvent) -> RetransmitDecision;
fn should_retransmit(&self, key: PacketKey) -> bool;
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct RetryLimitPolicy {
pub max_attempts: u8,
}
impl RetryLimitPolicy {
#[must_use]
pub const fn new(max_attempts: u8) -> Self {
Self { max_attempts }
}
}
impl RetransmitPolicy for RetryLimitPolicy {
fn on_timeout(&mut self, event: TimeoutEvent) -> RetransmitDecision {
if event.attempts < self.max_attempts {
RetransmitDecision::Retransmit { key: event.key }
} else {
RetransmitDecision::Drop { key: event.key }
}
}
fn should_retransmit(&self, _key: PacketKey) -> bool {
self.max_attempts > 0
}
}
#[cfg(test)]
mod tests {
use crate::core::{ChannelId, MessageId, PacketIndex, PacketKey};
use super::{RetransmitDecision, RetransmitPolicy, RetryLimitPolicy, TimeoutEvent};
#[test]
fn retry_limit_policy_drops_after_limit() {
let key = PacketKey::new(ChannelId::DEFAULT, MessageId::new(3), PacketIndex::ZERO);
let mut policy = RetryLimitPolicy::new(2);
assert_eq!(
policy.on_timeout(TimeoutEvent::new(key, 10, 1)),
RetransmitDecision::Retransmit { key }
);
assert_eq!(
policy.on_timeout(TimeoutEvent::new(key, 20, 2)),
RetransmitDecision::Drop { key }
);
}
}