Skip to content

BusinessMath 2.5.1 — Streaming producer-lifecycle fix

Latest

Choose a tag to compare

@jpurnell jpurnell released this 28 Jul 04:05
· 8 commits to main since this release

Fixes a correctness bug in the async streaming composition operators: their producer tasks could outlive or starve their consumer, spinning indefinitely (runaway CPU, unbounded memory, and — on constrained/CI hosts — preventing the process from exiting).

Fixed

  • Streaming producer-task lifecycle in merge, combineLatest, withLatestFrom, sample, debounce, timeout, and AsyncAlignedSequence:
    • Producer is cancelled when the consumer stops (onTermination → producer.cancel()).
    • Producer loops break when yield returns .terminated (consumer gone) — a reliable stop signal.
    • merge producers await Task.yield() per element so a non-suspending source can't monopolize the cooperative pool and starve the consumer.

Root-caused via a live sample() of the process hanging at exit on the macos-26 CI runner (all tests passed, then the process couldn't terminate).

Changed

  • CI workflow: fixed YAML indentation, added timeout-minutes and a hang-diagnostic watchdog.
  • De-flaked three pre-existing scheduler-dependent tests; raised over-tight hang-guard time limits.

🤖 Generated with Claude Code