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
//! Marking a session busy for the length of one command.
use Arc;
use ;
use crateResult;
/// Holds a session in [`SessionState::Active`] for as long as the guard lives,
/// and returns it to [`SessionState::Idle`] when the guard is dropped.
///
/// The pair used to be written by hand — a transition to `Active` before the
/// command and one back to `Idle` after it. That is correct only for the escape
/// paths someone remembered to count, and it misses the one no branch can
/// express: an `.await` that never resumes because the future was **cancelled**.
/// A caller that hangs up before its response is written leaves axum dropping
/// the handler mid-command, and the session stayed `Active` forever — reporting
/// a command running long after it had finished, while `idle_seconds` grew
/// underneath it. Measured, not reasoned about: 44.7 s after the caller vanished
/// from a nine-second command.
///
/// A guard closes every exit through one path, including cancellation, because
/// dropping a future runs the destructors of everything it owns.
pub