o_sfu_core/options/routing.rs
1use std::num::{NonZeroU64, NonZeroUsize};
2
3/// Same-room router cap and packet-loop health threshold.
4///
5/// Only running workers are eligible. A room's first join selects the first
6/// healthy worker in its cyclic search order or the least-delayed running worker
7/// when none qualify. Later joins prefer the least-delayed healthy assigned
8/// worker. If none qualifies, another router may be allocated on an unused healthy
9/// worker up to `max_local_routers` and the worker count. Otherwise, the
10/// least-delayed running assigned worker is reused. Missing delay samples and
11/// values at or above `packet_loop_delay_threshold_ms` are unhealthy.
12///
13/// Placements on failed workers do not count toward the cap. When no assigned
14/// worker is running, a join attaches a fresh placement on another running worker,
15/// even with the single-router policy. If no worker is running, admission returns
16/// [`RoomManagerJoinError::NoUsableWorker`](crate::server::room::RoomManagerJoinError::NoUsableWorker).
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub struct RoomWorkerPolicy {
19 max_local_routers: usize,
20 packet_loop_delay_threshold_ms: u64,
21}
22
23impl RoomWorkerPolicy {
24 pub const DEFAULT_PACKET_LOOP_DELAY_THRESHOLD_MS: u64 = 20;
25
26 #[must_use]
27 pub const fn strict_single_router() -> Self {
28 Self {
29 max_local_routers: 1,
30 packet_loop_delay_threshold_ms: Self::DEFAULT_PACKET_LOOP_DELAY_THRESHOLD_MS,
31 }
32 }
33
34 #[must_use]
35 pub const fn new(
36 max_local_routers: NonZeroUsize,
37 packet_loop_delay_threshold_ms: NonZeroU64,
38 ) -> Self {
39 Self {
40 max_local_routers: max_local_routers.get(),
41 packet_loop_delay_threshold_ms: packet_loop_delay_threshold_ms.get(),
42 }
43 }
44
45 #[must_use]
46 pub const fn max_local_routers(self) -> usize {
47 self.max_local_routers
48 }
49
50 #[must_use]
51 pub const fn packet_loop_delay_threshold_ms(self) -> u64 {
52 self.packet_loop_delay_threshold_ms
53 }
54}
55
56impl Default for RoomWorkerPolicy {
57 fn default() -> Self {
58 Self::strict_single_router()
59 }
60}