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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//! Session scope: which deliveries one session of this role serves.
//!
//! Scope is a workspace setting of the role (`[client.session]`, plan §10) and
//! it takes effect here and nowhere else: the server delivers by role and keeps
//! zero orchestration, so the client is the only party that decides which of its
//! sessions takes a delivery.
//!
//! The three scopes and what they key on:
//!
//! * `oneshot` serves one delivery. A session is born with the delivery that
//! opened it and closes when that delivery settles, so the resolution reaches
//! no existing session at all and the key is the delivery's own task.
//! * `task` serves every delivery one task family sends this role, keyed on
//! `causality.family` rather than on the task id: in planner → builder →
//! reviewer → builder the second delivery to builder enters the session
//! builder used the first time, which is the point of the scope.
//! * `role` serves a standing pool, at most `max_sessions` of them, and hands a
//! delivery to whichever pooled session has waited longest.
//!
//! A session that is serving nothing right now is `idle`: it keeps its process
//! and its row, and it takes the next delivery the scope sends it. An idle
//! session whose runtime can resume may have its process released by this client
//! ([`super::DispatchState::suspend_idle_sessions`]) and is then `suspended`:
//! the conversation survives in the runtime's own store, the slot spends no
//! capacity, and the next delivery bound to that session resumes it.
use DispatchInner;
use *;
use ;
/// The idle bound a scope carries when `[client.session] idle_close` is absent.
///
/// Two hours is the value the plan prints beside the scope table (§10). It is a
/// real bound rather than an absent one because a session that can never be
/// released is a process held for the life of the client, and the scope table
/// says an idle `task` or `role` session closes on its idle timeout.
pub const DEFAULT_IDLE_CLOSE: Duration = from_secs;
/// The family one delivery belongs to.
///
/// `causality.family` is minted with the root task and carried by every handoff
/// of that run, so every delivery one family sends this role names the same
/// value. A root minted before the field existed names none, and `Causality::root`
/// writes the task itself, so the fallback is the delivery's own task: such a
/// root is its own family, which is what it was before the field existed.
pub
/// The idle bound one policy carries, with the scope's own default filled in.
///
/// `None` is "never": a scope that opens one session per delivery has no idle
/// session to release at all, and `idle_close = 0` says the same for the other
/// two (the crate's other two duration knobs read zero the same way).
/// Whether one scope keys its sessions on the task family.
pub
/// Whether one session can take a delivery without spending a new slot.
///
/// A session holding no delivery is one the scope kept idle for the work that
/// belongs to it, and a suspended session is one whose slot the client already
/// gave back. Both are places a delivery runs in: the difference is which one
/// the placement hands it to, not whether the role has room for it.
pub
/// Where one delivery of `family` can run, as the role's scope resolves it.
///
/// The answer is about scope alone: capacity, the intake gate, and whether the
/// session found here can actually be handed the payload are the caller's
/// questions, because each of them has an answer that is not a placement.
pub
/// Resolve one delivery against the sessions this client holds.
///
/// A suspended session is preferred over opening a new one in every scope that
/// reuses sessions at all: resuming is what the released conversation is for.
/// Within a scope that hands deliveries to a pool, the session that has waited
/// longest is the one that takes the work.
pub