File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree 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