class

HTTP2::StreamBody

Inherits IO < Reference < Object

A bounded, read-only stream of inbound DATA octets.

Flow-control credit is returned only after bytes leave this buffer. Closing an unfinished body discards its buffered bytes and cancels the stream.

Constructors

new(capacity : Int32, on_consumed : Int32 -> Nil, on_cancel : -> Nil)
Source

Instance methods

buffered_bytes
Source
capacity
Source
close

Closes this IO.

IO defines this is a no-op method, but including types may override.

Source
closed?

Lock-free: @closed is an Atomic(Bool), and every write site (#close) publishes through the same atomic, so a plain #get here never tears — it can only be a snapshot that is momentarily stale under concurrent mutation, exactly as a mutex-guarded read would also have been the instant after releasing the lock.

Source
completed?

Lock-free; see #closed?. @terminal_error is only ever assigned once (under @mutex, in #terminate) and never cleared, so reading the reference here without the mutex is safe: reference reads/writes are atomic (no torn pointer), and the only possible staleness is "not yet visible," the same benign race a mutex-guarded read would have had the instant after releasing the lock.

Source
consumed_bytes

Cumulative count of bytes a caller has read out of this body via #read/#read_with_timeout, regardless of how those reads were split. Monotonically increasing for the body's lifetime; unaffected by bytes discarded on #close or #terminate. Comparing two snapshots taken across a wait tells whether a reader consumed anything during that window — used to detect an abandoned response without disturbing a reader that is merely slow (see HTTP2::Client#monitor_response).

:nodoc:

Source
finished?

Lock-free; see #closed?.

Source
read(slice : Bytes) : Int32

Reads at most slice.size bytes from this IO into slice. Returns the number of bytes read, which is 0 if and only if there is no more data to read (so checking for 0 is the way to detect end of file).

io = IO::Memory.new "hello"
slice = Bytes.new(4)
io.read(slice) # => 4
slice          # => Bytes[104, 101, 108, 108]
io.read(slice) # => 1
slice          # => Bytes[111, 101, 108, 108]
io.read(slice) # => 0
Source
read_with_timeout(slice : Bytes, timeout : Time::Span | Nil = nil, cancellation : Channel(Nil) | Nil = nil) : Int32

Reads with an optional inactivity timeout and cancellation signal.

:nodoc:

Source
terminate(error : Exception) : Int32

Marks the body terminal, discards buffered data, and returns the number of flow-controlled application octets that were discarded. Once the body is finished, closed, or terminal, this is a no-op returning 0 — the finished body's buffered data is deliberately preserved for the reader to drain to clean EOF, establishing an invariant against data loss.

:nodoc:

Source
write(slice : Bytes) : NoReturn

Writes the contents of slice into this IO.

io = IO::Memory.new
slice = Bytes.new(4) { |i| ('a'.ord + i).to_u8 }
io.write(slice)
io.to_s # => "abcd"
Source

Nested types