Skip to main content

StreamPolicy

Struct StreamPolicy 

Source
pub struct StreamPolicy {
    pub idle_timeout: Duration,
    pub total_timeout: Duration,
    pub max_bytes: usize,
}
Expand description

Per-operation bounds on a streamed response body, attached to a request as an extension and resolved by every implementation with StreamPolicy::of_request, the way HttpPolicy is. All fields clamp to the port maxima: a caller may only tighten.

The two timeouts divide the exchange along its one natural seam. The head — status and headers, everything known before the first byte of body — is bounded by HttpPolicy::timeout (at most 30 s, unchanged), because an upstream that cannot even answer is dead in the buffered world too. The body is bounded instead by idle_timeout, the quiet gap between two chunks (a model’s between-token pauses are normal; a stalled connection is not), and by total_timeout, the whole body’s ceiling measured from the head’s return. A body that streams steadily for twenty minutes is legal here and impossible under the 30 s cap — that is the feature, not a hole. Whichever bound ends the body names itself: the HttpError::DeadlineExceeded carries the idle gap when a quiet gap expired, and the whole-body ceiling when that is what the exchange ran out of.

max_bytes is enforced chunk by chunk (and against the declared Content-Length before the first chunk), the way the buffered cap is enforced against the whole body at once.

§Cloudflare Workers

On the Workers runtime these bounds are what makes streaming survivable there at all, because the platform’s own limits shape what a streamed exchange may cost (the numbers move; the authoritative page is https://developers.cloudflare.com/workers/platform/limits/):

  • There is no wall-clock limit on a request while the client stays connected, and time spent waiting on I/O does not count as CPU time — so a body that keeps arriving may legitimately run far past any CPU budget, and the port’s own idle and total ceilings are the only thing standing between a streaming caller and a connection the runtime would otherwise keep open indefinitely.
  • Subrequests per invocation are capped — a few dozen on the Free plan and a great many more on paid plans when this port was written (50 / 1,000; the paid ceiling has since been raised and made configurable) — and every hop of a redirect chain counts as one. A retry loop over streamed responses spends the budget on the head, as the buffered port always has.
  • At most 6 simultaneous open connections per invocation. A streamed exchange holds one of those six slots for its whole life, which under an idle-timeout-quota of minutes is a long time to hold a sixth of a request’s concurrency: the total ceiling exists to keep even a healthy stream from monopolising the pool.

Fields§

§idle_timeout: Duration

Largest gap allowed between two body chunks before the body is declared stalled and abandoned.

§total_timeout: Duration

Whole-body ceiling, measured from the moment the head returned.

§max_bytes: usize

Maximum accepted body size, enforced chunk by chunk.

Implementations§

Source§

impl StreamPolicy

Source

pub fn of_request<T>(request: &Request<T>) -> Self

The effective policy for request: the attached StreamPolicy extension if any, clamped to the port ceilings.

Source

pub fn clamped(self) -> Self

Clamps to MAX_STREAM_IDLE_TIMEOUT / MAX_STREAM_TOTAL_TIMEOUT / MAX_STREAM_BYTES: callers may lower a bound, never raise it.

Trait Implementations§

Source§

impl Clone for StreamPolicy

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for StreamPolicy

Source§

impl Debug for StreamPolicy

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for StreamPolicy

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Eq for StreamPolicy

Source§

impl PartialEq for StreamPolicy

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for StreamPolicy

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more