Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix AsyncIterableProducer.tee() to properly synchronize producers#298542

Open
kbhujbal wants to merge 1 commit intomicrosoft:mainfrom
kbhujbal:fix/async-iterable-producer-tee
Open

Fix AsyncIterableProducer.tee() to properly synchronize producers#298542
kbhujbal wants to merge 1 commit intomicrosoft:mainfrom
kbhujbal:fix/async-iterable-producer-tee

Conversation

@kbhujbal
Copy link
Contributor

@kbhujbal kbhujbal commented Mar 1, 2026

Fixes a known implementation issue in AsyncIterableProducer.tee() (added in #276037) where start() was called without being awaited inside executors, relying on implicit microtask ordering for correctness.

Problem

The previous implementation used a fire-and-forget start() call from each executor, with an early-return guard (if (!emitter1 || !emitter2) return). This was fragile — two test cases ('tee - empty source' and 'tee - handles errors in source') were skipped with a TODO noting the bug.

Solution

Restructure tee() to use explicit synchronization:

  • A bothReady deferred promise that signals when both emitters are available
  • A done deferred promise that keeps executors alive until source iteration completes
  • Source consumption starts via bothReady.p.then(...) instead of a fire-and-forget start() call

This makes the data flow explicit and eliminates reliance on microtask ordering.

Test plan

  • Unskipped 'tee - empty source' and 'tee - handles errors in source' tests
  • Removed TODO comments from all four tee test cases
  • Verified all tee tests pass (including stress test with 100 iterations)
  • Verified tee-of-tee composition works correctly

The previous implementation called `start()` without awaiting it inside
each executor, relying on implicit microtask ordering for correctness.
This was fragile and caused the empty source and error propagation test
cases to be skipped.

Restructure tee() to use an explicit `bothReady` deferred promise that
signals when both emitters are available, and a `done` deferred promise
that keeps the executors alive until source iteration completes. This
eliminates the fire-and-forget `start()` call and makes the data flow
explicit.

Also unskip the two previously skipped test cases ('tee - empty source'
and 'tee - handles errors in source') and remove the related TODO
comments from all four tee tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants