Class: Async::HTTP::Protocol::HTTP2::Output
- Inherits:
-
Object
- Object
- Async::HTTP::Protocol::HTTP2::Output
- Defined in:
- lib/async/http/protocol/http2/output.rb
Overview
Writes body data to an HTTP/2 stream, respecting flow control windows.
Instance Attribute Summary collapse
-
#trailer ⇒ Object
readonly
Returns the value of attribute trailer.
Instance Method Summary collapse
-
#close(error = nil) ⇒ Object
This method should only be called from within the context of the output task.
-
#close_write(error = nil) ⇒ Object
Finish writing to the stream.
-
#initialize(stream, body, trailer = nil) ⇒ Output
constructor
Initialize the output handler.
-
#start(parent: Task.current) ⇒ Object
Start an asynchronous task to write the body to the stream.
-
#stop(error) ⇒ Object
This method should only be called from within the context of the HTTP/2 stream.
-
#window_updated(size) ⇒ Object
Signal that the flow control window has been updated.
-
#write(chunk) ⇒ Object
Write a chunk of data to the HTTP/2 stream, respecting flow control.
Constructor Details
#initialize(stream, body, trailer = nil) ⇒ Output
Initialize the output handler.
18 19 20 21 22 23 24 25 26 27 |
# File 'lib/async/http/protocol/http2/output.rb', line 18 def initialize(stream, body, trailer = nil) @stream = stream @body = body @trailer = trailer @task = nil @guard = ::Mutex.new @window_updated = ::ConditionVariable.new end |
Instance Attribute Details
#trailer ⇒ Object (readonly)
Returns the value of attribute trailer.
29 30 31 |
# File 'lib/async/http/protocol/http2/output.rb', line 29 def trailer @trailer end |
Instance Method Details
#close(error = nil) ⇒ Object
This method should only be called from within the context of the output task.
86 87 88 89 |
# File 'lib/async/http/protocol/http2/output.rb', line 86 def close(error = nil) close_write(error) stop(error) end |
#close_write(error = nil) ⇒ Object
Finish writing to the stream.
78 79 80 81 82 83 |
# File 'lib/async/http/protocol/http2/output.rb', line 78 def close_write(error = nil) if stream = @stream @stream = nil stream.finish_output(error) end end |
#start(parent: Task.current) ⇒ Object
Start an asynchronous task to write the body to the stream.
32 33 34 35 36 37 38 39 40 |
# File 'lib/async/http/protocol/http2/output.rb', line 32 def start(parent: Task.current) raise "Task already started!" if @task if @body.stream? @task = parent.async(&self.method(:stream)) else @task = parent.async(&self.method(:passthrough)) end end |
#stop(error) ⇒ Object
This method should only be called from within the context of the HTTP/2 stream.
92 93 94 95 96 97 |
# File 'lib/async/http/protocol/http2/output.rb', line 92 def stop(error) if task = @task @task = nil task.stop(error) end end |
#window_updated(size) ⇒ Object
Signal that the flow control window has been updated.
45 46 47 48 49 50 51 |
# File 'lib/async/http/protocol/http2/output.rb', line 45 def window_updated(size) @guard.synchronize do @window_updated.signal end return true end |
#write(chunk) ⇒ Object
Write a chunk of data to the HTTP/2 stream, respecting flow control.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/async/http/protocol/http2/output.rb', line 55 def write(chunk) until chunk.empty? maximum_size = @stream.available_frame_size # We try to avoid synchronization if possible: if maximum_size <= 0 @guard.synchronize do maximum_size = @stream.available_frame_size while maximum_size <= 0 @window_updated.wait(@guard) maximum_size = @stream.available_frame_size end end end break unless chunk = send_data(chunk, maximum_size) end end |