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.
Summary
tokio_stream::itercurrently has an explicitTODO: add coop backand uses a localyield_amtcounter to returnPoll::Pendingafter 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.rsstoresyield_amtonIter<I>.poll_nextincrements the counter on each yielded item.Poll::Pending.// TODO: add coop back.This is not necessarily a correctness bug: a
Streamis allowed to returnPendingand later produce more items. The concern is more about scheduler integration and maintainability.Motivation
The current implementation effectively gives
tokio_stream::iterits 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:
Possible approach
One possible direction:
rt/coop-enabled configuration, use Tokio's cooperative budget mechanism inpoll_next;Suggested tests
Before changing behavior, it would be useful to add focused tests for:
size_hintcontinues to delegate to the underlying iterator;Question
Is restoring coop integration for
tokio_stream::iterstill desirable, or is the current manualyield_amtbehavior now the intended design?If the former, I would be happy to work on a small PR following maintainer guidance.