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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//! Waiting for a channel's transport to finish connecting, instead of
//! dropping the work that needed it (#1242).
//!
//! A wake for a channel session resolves its route, resolves its target, and
//! then asks the channel for the connected client it must send through. At
//! boot that client is often not there yet: the recovery pass and the
//! channel's own connect run concurrently, and nothing orders them. Every
//! adapter answered the same way, with a warn and a `return`:
//!
//! ```text
//! [bg-resume] telegram: bot not available; dropping resume
//! ```
//!
//! That is a permanent loss for a transport that was seconds away. It was
//! observed across ~21 daemon restarts in 48h, and in one case a background
//! result was never delivered at all, because the only thing that would have
//! retried it was the user happening to send a message.
//!
//! Waiting costs a boot a few hundred milliseconds and turns the race into a
//! non-event. The wait is bounded, because a channel that is not configured
//! in this run never connects and holding the task forever would leak one per
//! wake.
use Future;
use Duration;
use Uuid;
/// How long a wake waits for its channel's transport before giving up.
///
/// Deliberately the same window as
/// [`ROUTE_GRACE`](crate::brain::agent::service::restart_recovery::ROUTE_GRACE),
/// which is how long a parked restart report waits for a route before being
/// flushed locally. The two startup flush paths raced because they had
/// different, unstated readiness assumptions; giving them one window by
/// construction is what makes their ordering deterministic rather than
/// incidental. Change one and this fails to compile against the other.
pub const CONNECT_GRACE: Duration =
crateROUTE_GRACE;
/// Gap between readiness checks. Short enough that a wake follows its
/// connect closely rather than on the next whole second, cheap enough at this
/// interval that polling costs nothing next to a boot.
const POLL: Duration = from_millis;
/// Wait for `lookup` to produce a transport, up to [`CONNECT_GRACE`].
///
/// Returns `None` only when the whole window passed without one, which means
/// the channel is not coming up in this run. `lookup` is re-run per poll
/// rather than awaited once, because "connected" is a mutable slot the
/// channel fills from its own task, not a future that resolves.
///
/// The first check happens before any sleep, so the ordinary case (the
/// channel connected long ago) is exactly as fast as the bare check it
/// replaced.
pub async