1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// ════════════════════════════════════════════════════════════════════════════
// Error types
// ════════════════════════════════════════════════════════════════════════════
/// Error returned by blocking recv operations.
///
/// # Variants
///
/// - `Disconnected`: All senders have been dropped. For broadcast channels,
/// this means no new messages will arrive.
///
/// - `Lagged { skipped }`: *Only for bounded broadcast channels.* Indicates that
/// the receiver fell behind the sender(s) and missed `skipped` messages. The
/// receiver's cursor has been advanced to the oldest available message.
///
/// # Lag Recovery
///
/// When `Lagged { skipped }` is encountered, the receiver has been automatically
/// advanced to the oldest message still in the ring buffer. Typical recovery patterns:
///
/// ```text
/// match rx.recv() {
/// Ok(msg) => process(msg),
/// Err(RecvError::Lagged { skipped }) => {
/// eprintln!("Fell behind by {} messages", skipped);
/// // Continue receiving: the next recv() will return the oldest
/// // available message, not an error.
/// }
/// Err(RecvError::Disconnected) => {
/// eprintln!("All senders disconnected");
/// break;
/// }
/// }
/// ```
///
/// To avoid lag:
/// - Ensure receiver threads wake promptly (use select! with short timeouts)
/// - Consider increasing broadcast channel capacity if lag is frequent
/// - Process messages quickly in the recv handler
/// Error returned by non-blocking try_recv operations.
///
/// # Variants
///
/// - `Empty`: Channel is currently empty (but senders are still connected).
///
/// - `Disconnected`: All senders have been dropped.
///
/// - `Lagged { skipped }`: *Only for bounded broadcast channels.* The receiver
/// fell behind and missed `skipped` messages. The receiver's cursor has been
/// automatically advanced to recover.
///
/// # Retry Strategy
///
/// A typical pattern with try_recv:
///
/// ```text
/// loop {
/// match rx.try_recv() {
/// Ok(msg) => return process(msg),
/// Err(TryRecvError::Empty) => {
/// // No message ready, come back later
/// spin_wait();
/// }
/// Err(TryRecvError::Lagged { skipped }) => {
/// eprintln!("Receiver lagged by {} messages; recovering", skipped);
/// // Continue retrying: next try_recv will get the oldest available
/// }
/// Err(TryRecvError::Disconnected) => {
/// eprintln!("Channel closed");
/// return None;
/// }
/// }
/// }
/// ```
;