Class: Hyperion::ResponseWriter::ChunkedCoalescer
- Inherits:
-
Object
- Object
- Hyperion::ResponseWriter::ChunkedCoalescer
- Defined in:
- lib/hyperion/response_writer.rb
Overview
Per-response coalescing buffer. Holds <512 B chunks until either the 4 KiB threshold is hit, the 1 ms writer-fiber tick elapses, or an explicit flush / end-of-body fires. One instance per response; not shared across the connection (state lifecycle = response lifecycle, matches the Stepable-style “per-call object” pattern).
Instance Attribute Summary collapse
-
#bytes_written ⇒ Object
readonly
Returns the value of attribute bytes_written.
-
#coalesced_write_count ⇒ Object
readonly
Returns the value of attribute coalesced_write_count.
-
#total_write_count ⇒ Object
readonly
Returns the value of attribute total_write_count.
Instance Method Summary collapse
-
#flush_and_terminate! ⇒ Object
End-of-body.
-
#force_flush! ⇒ Object
External flush (body responded to flush, or yielded the flush sentinel).
-
#initialize(io) ⇒ ChunkedCoalescer
constructor
A new instance of ChunkedCoalescer.
-
#write_chunk(payload) ⇒ Object
Append a chunk into the wire stream.
Constructor Details
#initialize(io) ⇒ ChunkedCoalescer
Returns a new instance of ChunkedCoalescer.
449 450 451 452 453 454 455 456 457 |
# File 'lib/hyperion/response_writer.rb', line 449 def initialize(io) @io = io @buffer = String.new(capacity: ResponseWriter::COALESCE_FLUSH_BYTES, encoding: Encoding::ASCII_8BIT) @bytes_written = 0 @total_write_count = 0 @coalesced_write_count = 0 @last_drain_at = monotonic_now end |
Instance Attribute Details
#bytes_written ⇒ Object (readonly)
Returns the value of attribute bytes_written.
447 448 449 |
# File 'lib/hyperion/response_writer.rb', line 447 def bytes_written @bytes_written end |
#coalesced_write_count ⇒ Object (readonly)
Returns the value of attribute coalesced_write_count.
447 448 449 |
# File 'lib/hyperion/response_writer.rb', line 447 def coalesced_write_count @coalesced_write_count end |
#total_write_count ⇒ Object (readonly)
Returns the value of attribute total_write_count.
447 448 449 |
# File 'lib/hyperion/response_writer.rb', line 447 def total_write_count @total_write_count end |
Instance Method Details
#flush_and_terminate! ⇒ Object
End-of-body. Drain any buffered bytes AND emit the chunked terminator in a single syscall — this preserves the “terminator follows the last chunk atomically” invariant on the wire (otherwise a peer could see a half-flushed response if the writer fiber were preempted between our flush + terminator writes).
489 490 491 492 493 494 495 496 |
# File 'lib/hyperion/response_writer.rb', line 489 def flush_and_terminate! if @buffer.empty? do_write(ResponseWriter::CHUNKED_TERMINATOR) else @buffer << ResponseWriter::CHUNKED_TERMINATOR drain_buffer! end end |
#force_flush! ⇒ Object
External flush (body responded to flush, or yielded the flush sentinel). Drains the buffer; safe to call when the buffer is empty.
480 481 482 |
# File 'lib/hyperion/response_writer.rb', line 480 def force_flush! drain_buffer! end |
#write_chunk(payload) ⇒ Object
Append a chunk into the wire stream. Small chunks coalesce into the buffer; large chunks drain the buffer first then write directly. Returns the number of body-bytes consumed (used by metrics).
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 |
# File 'lib/hyperion/response_writer.rb', line 462 def write_chunk(payload) framed = frame_chunk(payload) if payload.bytesize < ResponseWriter::COALESCE_SMALL_CHUNK_BYTES append_to_buffer(framed) maybe_tick_flush else # Big chunk: drain anything we've accumulated first so that # bytes hit the wire in body-yield order, then write the big # chunk in its own syscall (no point coalescing — it's already # past the threshold). drain_buffer! do_write(framed) end payload.bytesize end |