Skip to content

Commit 9c526e7

Browse files
committed
refactor-request-queue: fixes
We basically never want to call `Queue.clear` because the head of the queue has special semantic meaning. Instead, we never try to clear the queue and rely on the fact that the queue will never be advanced. This is easy to reason about because the only time we advance the request queue is when the current request is not persistent. I added an explicit test of this situation to build confidence. Additionally, there was an incorrect assertion that you couldn't finish a write with reads still pending. A test was added upstream and it no longer fails with this fix. The final change was some subtle but unused code. In the write loop, we have something that decides to shutdown the connection if the reader is closed, parallel to the next read operation. But this felt weird, the reader should always be awake in the case that it is closed, which means that either 1) it will shutdown the connection or 2) it will wait for the writer, which will wake the reader once it's advanced the request queue, and then it will shutdown the connection.
1 parent 47528e1 commit 9c526e7

2 files changed

Lines changed: 7 additions & 10 deletions

File tree

lib/server_connection.ml

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ let error_code t =
155155
else None
156156

157157
let shutdown t =
158-
Queue.clear t.request_queue;
159158
shutdown_reader t;
160159
shutdown_writer t;
161160
wakeup_reader t;
@@ -190,7 +189,8 @@ let advance_request_queue t =
190189
;;
191190

192191
let rec _next_read_operation t =
193-
if not (is_active t) then (
192+
if not (is_active t)
193+
then (
194194
if Reader.is_closed t.reader
195195
then shutdown t;
196196
Reader.next t.reader
@@ -216,7 +216,6 @@ and _final_read_operation_for t reqd =
216216

217217
let next_read_operation t =
218218
match _next_read_operation t with
219-
(* XXX(dpatti): These two [`Error _] constructors are never returned *)
220219
| `Error (`Parse _) -> set_error_and_handle t `Bad_request; `Close
221220
| `Error (`Bad_request request) -> set_error_and_handle ~request t `Bad_request; `Close
222221
| (`Read | `Yield | `Close) as operation -> operation
@@ -248,11 +247,9 @@ let read_eof t bs ~off ~len =
248247
read_with_more t bs ~off ~len Complete
249248

250249
let rec _next_write_operation t =
251-
if not (is_active t) then (
252-
if Reader.is_closed t.reader
253-
then shutdown t;
254-
Writer.next t.writer
255-
) else (
250+
if not (is_active t)
251+
then Writer.next t.writer
252+
else (
256253
let reqd = current_reqd_exn t in
257254
match Reqd.output_state reqd with
258255
| Waiting ->
@@ -274,7 +271,7 @@ and _final_write_operation_for t reqd =
274271
Writer.next t.writer;
275272
) else (
276273
match Reqd.input_state reqd with
277-
| Ready -> assert false
274+
| Ready -> Writer.next t.writer;
278275
| Complete ->
279276
advance_request_queue t;
280277
_next_write_operation t;

lib_test/test_server_connection.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ let test_multiple_requests_in_single_read () =
647647
request_to_string (Request.create `GET "/")
648648
in
649649
read_string t reqs;
650-
reader_yielded t;
650+
reader_ready t;
651651
Alcotest.(check int) "fired handler of both requests" 2 !reqs_handled
652652
;;
653653

0 commit comments

Comments
 (0)