File tree 4 files changed +78
-62
lines changed
4 files changed +78
-62
lines changed Load Diff This file was deleted.
Original file line number Diff line number Diff line change 14
14
require "traces/provider"
15
15
16
16
require_relative "protocol"
17
- require_relative "body/finishable"
18
17
19
18
module Async
20
19
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 7
7
# Copyright, 2024, by Anton Zhuravsky.
8
8
9
9
require_relative "connection"
10
- require_relative "../../body/ finishable"
10
+ require_relative "finishable"
11
11
12
12
require "console/event/failure"
13
13
@@ -16,6 +16,18 @@ module HTTP
16
16
module Protocol
17
17
module HTTP1
18
18
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
+
19
31
def fail_request ( status )
20
32
@persistent = false
21
33
write_response ( @version , status , { } )
@@ -26,6 +38,11 @@ def fail_request(status)
26
38
end
27
39
28
40
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
+
29
46
# The default is true.
30
47
return unless @persistent
31
48
@@ -49,7 +66,7 @@ def each(task: Task.current)
49
66
50
67
while request = next_request
51
68
if body = request . body
52
- finishable = Body :: Finishable . new ( body )
69
+ finishable = Finishable . new ( body )
53
70
request . body = finishable
54
71
end
55
72
@@ -126,10 +143,8 @@ def each(task: Task.current)
126
143
request &.finish
127
144
end
128
145
146
+ # Discard or wait for the input body to be consumed:
129
147
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
133
148
rescue => error
134
149
raise
135
150
ensure
You can’t perform that action at this time.
0 commit comments