Skip to content

tokio-stream: consider restoring cooperative budgeting in iter #8207

@spellsaif

Description

@spellsaif

Summary

tokio_stream::iter currently has an explicit TODO: add coop back and uses a local yield_amt counter to return Poll::Pending after every 32 yielded items.

Would it make sense to restore integration with Tokio's cooperative budgeting when the relevant Tokio runtime feature is available, while keeping the current simple fallback for configurations without it?

Context

Current implementation:

  • tokio-stream/src/iter.rs stores yield_amt on Iter<I>.
  • poll_next increments the counter on each yielded item.
  • Once the counter reaches 32, it resets the counter, wakes the current task, and returns Poll::Pending.
  • The code has an explicit comment: // TODO: add coop back.

This is not necessarily a correctness bug: a Stream is allowed to return Pending and later produce more items. The concern is more about scheduler integration and maintainability.

Motivation

The current implementation effectively gives tokio_stream::iter its own hard-coded cooperative-yield policy. That seems slightly separate from Tokio's broader cooperative scheduling machinery.

Using Tokio's cooperative budget where available could:

  • keep fairness behavior aligned with the runtime's existing coop mechanisms;
  • avoid a standalone magic number in this adapter;
  • make behavior easier to reason about alongside other budget-aware Tokio primitives;
  • potentially make runtime metrics and forced-yield behavior more consistent.

Possible approach

One possible direction:

  • under the appropriate Tokio rt/coop-enabled configuration, use Tokio's cooperative budget mechanism in poll_next;
  • preserve the current lightweight fallback behavior where coop is not available;
  • keep the public API and item semantics unchanged.

Suggested tests

Before changing behavior, it would be useful to add focused tests for:

  • a large finite iterator does not starve a sibling task under a Tokio runtime;
  • size_hint continues to delegate to the underlying iterator;
  • EOF behavior around the current 32-item boundary does not rely on an extra spurious pending poll;
  • behavior remains sensible when Tokio runtime features are not enabled.

Question

Is restoring coop integration for tokio_stream::iter still desirable, or is the current manual yield_amt behavior now the intended design?

If the former, I would be happy to work on a small PR following maintainer guidance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-tokio-streamArea: The tokio-stream crate

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions