struct

HTTP2::Client::Timeouts

Inherits Struct < Value < Object

Per-operation deadlines. Nil disables the corresponding timeout.

connect covers DNS and TCP dialing, read covers the TLS and HTTP/2 handshakes (for https origins, the TLS handshake itself; then, for both schemes, the wait for the peer's SETTINGS after dialing) and each response-header wait, write covers transport writes, and idle covers a blocked response-body read or trailer wait. There is no persistent socket-level read timeout, so a quiet-but-healthy connection (an idle pooled connection, a long-lived SSE or long-poll stream) is never killed merely for going quiet between waits. Liveness on an established connection is keepalive's job instead: connection_configuration's keepalive_interval/keepalive_timeout (30 seconds / 10 seconds by default for HTTP2::Client) periodically PINGs the peer and fails the connection if it stops answering; supply a configuration with keepalive_interval: nil to disable it.

idle also bounds a Response that the caller abandons — never reads, never closes — but ONLY while its body is actually pinning connection-window credit (unread buffered bytes sitting in it). Each time idle elapses with unread buffered data present and no bytes consumed since the previous check, the response's stream is canceled: flow-control credit for that buffered data is returned, RST_STREAM is sent, and the body is left with a terminal error, so a later read raises that specific error (e.g. RequestTimeoutError here). A caller's own Response#close also makes a later read raise rather than return a silent EOF, but with a generic IO::Error ("Closed stream") instead of a stream's own terminal error — a library-initiated reclamation stays distinguishable from a caller's own graceful stop by exception type, not by whether reading raises at all. If any bytes WERE consumed in that window, the deadline simply re-arms, so a slow-but-active reader is never killed. A quiet stream with an EMPTY buffer — an SSE or long-poll response waiting between events, a successful CONNECT tunnel sitting quiet while the app uploads — pins no credit and keeps running indefinitely: the "never killed merely for going quiet" contract above still holds for it. Set idle: nil to disable this safety net along with the per-read/trailer timeout it shares the setting with.

stream_slot is the pool-wide request-capacity budget. A request first tries every eligible connection and may start one shared, demand-driven expansion dial. nil (the default) performs that growth but raises PoolSaturatedError as soon as the pool can make no further progress. A span waits up to that long for any connection to gain capacity, for an expansion dial, or for a SETTINGS increase. Cancellation and client close interrupt the wait. Atomic logical reservations do not consume stream IDs while waiting, and opening on one connection does not serialize opening on another connection.

Constructors

new(connect : Time::Span | Nil = 10.seconds, read : Time::Span | Nil = 30.seconds, write : Time::Span | Nil = 30.seconds, idle : Time::Span | Nil = 30.seconds, stream_slot : Time::Span | Nil = nil)
Source

Instance methods

connect
Source
idle
Source
read
Source
stream_slot
Source
write
Source