Implement congestion controller trait over `enum`
Opened this issue · 0 comments
camshaft commented
Problem:
Due to the endpoint builder preferring completely static types, it makes it difficult to swap implementations of providers based on config:
let builder = if use_bbr {
build.with_congestion_controller(congestion_controller::Bbr::default())?
} else {
build.with_congestion_controller(congestion_controller::Cubic::default())?
};
Solution:
To make this pattern easier, we can provide an enum impl that is implemented generically for two different CCAs and dispatches at runtime:
enum Either<A, B> {
Left(A),
Right(B),
}
impl<A, B> CongestionController for Either<A, B>
where
A: CongestionController,
B: CongestionController,
{
type PacketInfo = Either<A::PacketInfo, B::PacketInfo>;
#[inline]
fn congestion_window(&self) -> u32 {
match self {
Self::Left(cca) => cca.congestion_window(),
Self::Right(cca) => cca.congestion_window(),
}
}
...
}
The application would then be able to switch at runtime:
let builder = if use_bbr {
build.with_congestion_controller(Either::Left(congestion_controller::Bbr::default()))?
} else {
build.with_congestion_controller(Either::Right(congestion_controller::Cubic::default()))?
};
It might make sense to use the either crate, or just define our own in s2n-quic-core
to avoid the dependency.