Commit 617816a
committed
refactor request queue mechanics
This is a prelude to #159 which introduces upgrade requests, and much
of the diff is identical, with a few trivial changes in `Reqd` and a few
major changes in `Server_connection`.
The goals here are:
1. Make `Reqd` return better types that encapsulate its state instead of
requiring the user to probe it with `requires_<input|output>` and
`is_complete`.
2. Try to make queue management easier to reason about by folding bits
of logic from `advance_request_queue_if_necessary` into
`next_read_operation` and `next_write_operation` such that we only
perform side-effects when the operation in question demands it.
One of the ways I tried to make this easier to reason about was to make
the `yield_<reader|writer>` and `next_<read|write>_operation` functions
very parallel. For one, the extra logic in `yield_writer` was puzzling.
Ideally, if you're calling `yield_writer`, you're doing so because you
just called `next_action` and were told to `Yield`, so all of the
conditions being checked should not be possible.
Looking at the next-operation functions, they both start out with a
short-circuit for shutting down when the server can no longer make
progress (reader is closed and queue is empty). This doesn't feel like
it belongs here. Perhaps this check should be part of
`advance_request_queue` with some extra logic triggering in
`shutdown_reader`? After that, the next-operation functions use some
very simple probing of the input/output state of `Reqd` to determine
what to do next. Only in the case of `Complete` do we move into a
separate function (to make it easier to read):
`_final_<read|write>_operation`.
In these functions, we decide if we should shutdown the respective
reader/writer or consider the `reqd` complete and move it off the queue.
When we do shift it off, we recursively ask for the next operation given
the new queue state. In all cases, before we return the result, we
wakeup the other side so that it too can evaluate the next operation
given the new queue state.
Though on the surface, these pieces feel fairly straightforward, there
are still a slew of re-entrancy bugs to consider. I think there are two
things that we can do to make this drastically easier to manage:
1. We call `t.request_handler` in two places, and this is mostly because
we want to keep the invariant that the head of the request queue has
already been passed off to the handler. I feel like splitting this up
into a simple queue of unhandled requests and a [Reqd.t option] that
represents the current request would be easier to manage.
2. It would be nice to schedule calls. Things like waking up the writer
before you let the read loop know its next operation just immediately
makes my mind fall apart and lose track of state. There's a fairly
obvious solution of asking for a `schedule : (unit -> unit) -> unit`
function from the runtime that promises to not call the thunk
synchronously, but rather waits until it is outside of the read and
write loops. But maybe we can solve it using what we have now, like
establishing a contract that when the reader/writer is woken up, they
must schedule their work for a fresh call stack and not immediately
ask for operations.
I added a `Queue.clear` to shutdown, not because it was necessary in any
sense, but because it was part of `advance_request_queue_if_necessary`,
which could have come into play in certain situations where `shutdown`
was called from the runtime (e.g., in case of some exception).
I would like to note that despite the fact that all tests pass, I have
very little confidence in this being correct right now and would like to
do some further testing within the actual runtimes.1 parent e8e8f89 commit 617816a
2 files changed
Lines changed: 64 additions & 55 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
243 | 243 | | |
244 | 244 | | |
245 | 245 | | |
246 | | - | |
247 | | - | |
248 | | - | |
249 | | - | |
250 | | - | |
251 | | - | |
252 | | - | |
253 | | - | |
254 | | - | |
255 | 246 | | |
256 | 247 | | |
257 | 248 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
84 | | - | |
| 84 | + | |
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
| |||
155 | 155 | | |
156 | 156 | | |
157 | 157 | | |
| 158 | + | |
158 | 159 | | |
159 | 160 | | |
160 | 161 | | |
| |||
182 | 183 | | |
183 | 184 | | |
184 | 185 | | |
185 | | - | |
186 | | - | |
187 | | - | |
188 | | - | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | | - | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
197 | | - | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
204 | | - | |
205 | | - | |
206 | | - | |
207 | | - | |
208 | | - | |
209 | | - | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
214 | | - | |
215 | | - | |
216 | | - | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
217 | 198 | | |
218 | 199 | | |
219 | 200 | | |
220 | | - | |
221 | | - | |
222 | | - | |
223 | | - | |
224 | | - | |
225 | | - | |
| 201 | + | |
226 | 202 | | |
227 | | - | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
228 | 219 | | |
229 | 220 | | |
230 | 221 | | |
231 | 222 | | |
| 223 | + | |
232 | 224 | | |
233 | 225 | | |
234 | 226 | | |
| |||
259 | 251 | | |
260 | 252 | | |
261 | 253 | | |
262 | | - | |
263 | | - | |
264 | | - | |
265 | | - | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
266 | 260 | | |
267 | | - | |
268 | | - | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
269 | 287 | | |
270 | 288 | | |
271 | 289 | | |
0 commit comments