Class: Hyperion::Http2Handler::WriterContext
- Inherits:
-
Object
- Object
- Hyperion::Http2Handler::WriterContext
- Defined in:
- lib/hyperion/http2_handler.rb
Overview
Holds the per-connection outbound coordination state (queue, notifications, byte counters, shutdown flag) plus the encode mutex that protects HPACK state and per-stream frame ordering.
Single instance per connection, lives for the lifetime of ‘serve`.
Instance Attribute Summary collapse
-
#encode_mutex ⇒ Object
readonly
Returns the value of attribute encode_mutex.
Instance Method Summary collapse
-
#enqueue(bytes) ⇒ Object
Called by SendQueueIO#write on the calling (encoder) fiber.
-
#initialize(max_pending_bytes: MAX_PER_CONN_PENDING_BYTES) ⇒ WriterContext
constructor
A new instance of WriterContext.
-
#note_drained(bytesize) ⇒ Object
Called by the writer fiber after each successful drain to release any encoders blocked on the cap.
- #pending_bytes ⇒ Object
- #queue_empty? ⇒ Boolean
- #shutdown! ⇒ Object
-
#try_pop ⇒ Object
Pops a single chunk; returns nil if the queue is empty (non-blocking).
- #wait_for_signal ⇒ Object
- #writer_done? ⇒ Boolean
Constructor Details
#initialize(max_pending_bytes: MAX_PER_CONN_PENDING_BYTES) ⇒ WriterContext
Returns a new instance of WriterContext.
136 137 138 139 140 141 142 143 144 145 |
# File 'lib/hyperion/http2_handler.rb', line 136 def initialize(max_pending_bytes: MAX_PER_CONN_PENDING_BYTES) @queue = ::Thread::Queue.new @send_notify = ::Async::Notification.new @drained_notify = ::Async::Notification.new @encode_mutex = ::Mutex.new @pending_bytes = 0 @pending_bytes_lock = ::Mutex.new @max_pending_bytes = max_pending_bytes @writer_done = false end |
Instance Attribute Details
#encode_mutex ⇒ Object (readonly)
Returns the value of attribute encode_mutex.
134 135 136 |
# File 'lib/hyperion/http2_handler.rb', line 134 def encode_mutex @encode_mutex end |
Instance Method Details
#enqueue(bytes) ⇒ Object
Called by SendQueueIO#write on the calling (encoder) fiber. Enforces the per-connection backpressure cap before enqueuing.
149 150 151 152 153 154 |
# File 'lib/hyperion/http2_handler.rb', line 149 def enqueue(bytes) wait_for_drain_if_full(bytes.bytesize) @pending_bytes_lock.synchronize { @pending_bytes += bytes.bytesize } @queue << bytes @send_notify.signal end |
#note_drained(bytesize) ⇒ Object
Called by the writer fiber after each successful drain to release any encoders blocked on the cap.
165 166 167 168 169 170 171 |
# File 'lib/hyperion/http2_handler.rb', line 165 def note_drained(bytesize) @pending_bytes_lock.synchronize do @pending_bytes -= bytesize @pending_bytes = 0 if @pending_bytes.negative? # paranoia end @drained_notify.signal end |
#pending_bytes ⇒ Object
192 193 194 |
# File 'lib/hyperion/http2_handler.rb', line 192 def pending_bytes @pending_bytes_lock.synchronize { @pending_bytes } end |
#queue_empty? ⇒ Boolean
188 189 190 |
# File 'lib/hyperion/http2_handler.rb', line 188 def queue_empty? @queue.empty? end |
#shutdown! ⇒ Object
177 178 179 180 181 182 |
# File 'lib/hyperion/http2_handler.rb', line 177 def shutdown! @writer_done = true # Wake the writer if it's parked, and any encoder waiting on drain. @send_notify.signal @drained_notify.signal end |
#try_pop ⇒ Object
Pops a single chunk; returns nil if the queue is empty (non-blocking).
157 158 159 160 161 |
# File 'lib/hyperion/http2_handler.rb', line 157 def try_pop @queue.pop(true) rescue ::ThreadError nil end |
#wait_for_signal ⇒ Object
173 174 175 |
# File 'lib/hyperion/http2_handler.rb', line 173 def wait_for_signal @send_notify.wait end |
#writer_done? ⇒ Boolean
184 185 186 |
# File 'lib/hyperion/http2_handler.rb', line 184 def writer_done? @writer_done end |