o_sfu_protocol/core/
request_tracker.rs1use std::mem;
4
5use super::{
6 Command, Commands, PendingRequestKind,
7 timers::{REQUEST_TIMEOUT_TIMER_BASE, RequestTimeoutId},
8};
9use crate::signaling::RequestId;
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12struct PendingRequestState {
13 request_id: RequestId,
14 kind: PendingRequestKind,
15 timeout_timer_id: RequestTimeoutId,
16}
17
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub(super) struct PendingRequestStart {
20 pub(super) request_id: RequestId,
21 pub(super) timeout_timer_id: RequestTimeoutId,
22}
23
24#[derive(Debug, Clone, PartialEq, Eq)]
26pub(super) struct RequestTracker {
27 next_request_counter: u64,
28 next_timeout_timer_id: RequestTimeoutId,
29 pending_requests: Vec<PendingRequestState>,
30}
31
32impl Default for RequestTracker {
33 fn default() -> Self {
34 Self::new()
35 }
36}
37
38impl RequestTracker {
39 pub(super) const fn new() -> Self {
40 Self {
41 next_request_counter: 0,
42 next_timeout_timer_id: REQUEST_TIMEOUT_TIMER_BASE,
43 pending_requests: Vec::new(),
44 }
45 }
46
47 pub(super) fn begin(&mut self, kind: PendingRequestKind) -> PendingRequestStart {
48 let request_id = self.allocate_request_id();
49 let timeout_timer_id = self.allocate_timeout_timer_id();
50 self.pending_requests.push(PendingRequestState {
51 request_id: request_id.clone(),
52 kind,
53 timeout_timer_id,
54 });
55 PendingRequestStart {
56 request_id,
57 timeout_timer_id,
58 }
59 }
60
61 pub(super) fn resolve_response(
62 &mut self,
63 response_to: &RequestId,
64 expected_kind: PendingRequestKind,
65 ok: bool,
66 ) -> Commands {
67 let Some(index) = self.pending_requests.iter().position(|pending_request| {
68 pending_request.request_id == *response_to && pending_request.kind == expected_kind
69 }) else {
70 return Vec::new();
71 };
72 vec![complete_pending_request(
74 self.pending_requests.remove(index),
75 ok,
76 )]
77 }
78
79 pub(super) fn resolve_timeout(&mut self, timeout_id: RequestTimeoutId) -> Option<Commands> {
80 let index = self
81 .pending_requests
82 .iter()
83 .position(|pending_request| pending_request.timeout_timer_id == timeout_id)?;
84 Some(vec![reject_pending_request(
85 self.pending_requests.remove(index),
86 "bus request timed out",
87 )])
88 }
89
90 pub(super) fn clear(&mut self) {
91 self.pending_requests.clear();
92 }
93
94 pub(super) fn fail_all(&mut self) -> Commands {
96 mem::take(&mut self.pending_requests)
97 .into_iter()
98 .map(|pending_request| reject_pending_request(pending_request, "bus closed"))
99 .collect()
100 }
101
102 fn allocate_request_id(&mut self) -> RequestId {
103 let request_id = RequestId::new(self.next_request_counter.to_string());
104 self.next_request_counter = self.next_request_counter.saturating_add(1);
105 request_id
106 }
107
108 fn allocate_timeout_timer_id(&mut self) -> RequestTimeoutId {
109 let timer_id = self.next_timeout_timer_id;
110 self.next_timeout_timer_id = timer_id.next();
111 timer_id
112 }
113}
114
115fn complete_pending_request(pending_request: PendingRequestState, ok: bool) -> Command {
116 Command::CompletePendingRequest {
117 request_id: pending_request.request_id,
118 timeout_timer_id: pending_request.timeout_timer_id.raw(),
119 ok,
120 }
121}
122
123fn reject_pending_request(pending_request: PendingRequestState, error: &str) -> Command {
124 Command::RejectPendingRequest {
125 request_id: pending_request.request_id,
126 timeout_timer_id: pending_request.timeout_timer_id.raw(),
127 error: error.to_owned(),
128 }
129}