File tree Expand file tree Collapse file tree 4 files changed +78
-62
lines changed
Expand file tree Collapse file tree 4 files changed +78
-62
lines changed Load Diff This file was deleted.
Original file line number Diff line number Diff line change 1414require "traces/provider"
1515
1616require_relative "protocol"
17- require_relative "body/finishable"
1817
1918module Async
2019 module HTTP
Original file line number Diff line number Diff line change 1+ # frozen_string_literal: true
2+
3+ # Released under the MIT License.
4+ # Copyright, 2024, by Samuel Williams.
5+
6+ require "protocol/http/body/wrapper"
7+ require "async/variable"
8+
9+ module Async
10+ module HTTP
11+ module Protocol
12+ module HTTP1
13+ # Keeps track of whether a body is being read, and if so, waits for it to be closed.
14+ class Finishable < ::Protocol ::HTTP ::Body ::Wrapper
15+ def initialize ( body )
16+ super ( body )
17+
18+ @closed = Async ::Variable . new
19+ @error = nil
20+
21+ @reading = false
22+ end
23+
24+ def reading?
25+ @reading
26+ end
27+
28+ def read
29+ @reading = true
30+
31+ super
32+ end
33+
34+ def close ( error = nil )
35+ unless @closed . resolved?
36+ @error = error
37+ @closed . value = true
38+ end
39+
40+ super
41+ end
42+
43+ def wait
44+ if @reading
45+ @closed . wait
46+ else
47+ self . discard
48+ end
49+ end
50+
51+ def inspect
52+ "#<#{ self . class } closed=#{ @closed } error=#{ @error } > | #{ super } "
53+ end
54+ end
55+ end
56+ end
57+ end
58+ end
Original file line number Diff line number Diff line change 77# Copyright, 2024, by Anton Zhuravsky.
88
99require_relative "connection"
10- require_relative "../../body/ finishable"
10+ require_relative "finishable"
1111
1212require "console/event/failure"
1313
@@ -16,6 +16,18 @@ module HTTP
1616 module Protocol
1717 module HTTP1
1818 class Server < Connection
19+ def initialize ( ...)
20+ super
21+
22+ @ready = Async ::Notification . new
23+ end
24+
25+ def closed!
26+ super
27+
28+ @ready . signal
29+ end
30+
1931 def fail_request ( status )
2032 @persistent = false
2133 write_response ( @version , status , { } )
@@ -26,6 +38,11 @@ def fail_request(status)
2638 end
2739
2840 def next_request
41+ # Wait for the connection to become idle before reading the next request:
42+ unless idle?
43+ @ready . wait
44+ end
45+
2946 # The default is true.
3047 return unless @persistent
3148
@@ -49,7 +66,7 @@ def each(task: Task.current)
4966
5067 while request = next_request
5168 if body = request . body
52- finishable = Body :: Finishable . new ( body )
69+ finishable = Finishable . new ( body )
5370 request . body = finishable
5471 end
5572
@@ -126,10 +143,8 @@ def each(task: Task.current)
126143 request &.finish
127144 end
128145
146+ # Discard or wait for the input body to be consumed:
129147 finishable &.wait
130-
131- # This ensures we yield at least once every iteration of the loop and allow other fibers to execute.
132- task . yield
133148 rescue => error
134149 raise
135150 ensure
You can’t perform that action at this time.
0 commit comments