Skip to content

fix(streaming): replace sleep gate with _started event for cancel tests#1146

Draft
planetf1 wants to merge 2 commits into
generative-computing:mainfrom
planetf1:worktree-fix-1132
Draft

fix(streaming): replace sleep gate with _started event for cancel tests#1146
planetf1 wants to merge 2 commits into
generative-computing:mainfrom
planetf1:worktree-fix-1132

Conversation

@planetf1
Copy link
Copy Markdown
Contributor

@planetf1 planetf1 commented May 22, 2026

Misc PR

Type of PR

  • Bug Fix
  • New Feature
  • Documentation
  • Other

Description

Two streaming cancellation tests gated on await asyncio.sleep(0.01) before calling cancel(). On a fast runner, StreamingMockBackend (only sleep(0) between tokens) can drain the whole 200-word stream inside that window — cancel() then no-ops on an already-done task and no CancelledError is raised.

Adds _orchestration_started (asyncio.Event) to StreamChunkingResult, set synchronously at the top of _orchestrate_streaming before any await. The two tests now wait on this event instead of sleeping: once it fires the task is suspended at its first real I/O point, so cancel() is guaranteed to land on a live task. An assert not task.done() guard follows the wait to catch any future regression to vacuous-pass behaviour.

Testing

  • Tests added to the respective file if code was changed
  • New code has 100% coverage if code as added
  • Ensure existing tests and github automation passes (a maintainer will kick off the github automation when the rest of the PR is populated)

Attribution

  • AI coding assistants used

@github-actions github-actions Bot added the bug Something isn't working label May 22, 2026
test_external_task_cancellation_releases_consumers and
test_external_cancellation_acomplete_raise_once both slept 10 ms before
calling cancel() on the orchestration task.  On a fast runner the mock
backend (sleep(0) between tokens) can drain the entire stream within that
window, making cancel() a no-op on an already-done task — no
CancelledError is ever raised and the test fails.

Add StreamChunkingResult._started (asyncio.Event), set at the very top of
_orchestrate_streaming before its first suspension point.  Tests now await
_started before cancelling: after _started fires the orchestration is live
but suspended, and cancel() is called without yielding back to the event
loop, so the task cannot complete between the two calls.

Fixes generative-computing#1132

Assisted-by: Claude Code
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
@planetf1 planetf1 force-pushed the worktree-fix-1132 branch from fa5713d to 767d0b9 Compare May 22, 2026 10:14
…ne() guard

Three improvements from code review:

- Rename _started to _orchestration_started for consistency with the
  existing _orchestration_task and _orchestration_exception fields.
- Expand the attribute comment to make explicit that the event is set
  synchronously before any await, and that the object is single-use.
- Add `assert not result._orchestration_task.done()` after the
  _orchestration_started.wait() in both cancellation tests as a
  regression guard: if a future change makes the orchestration
  synchronous to its first yield, the tests would silently regress to
  vacuous-pass without this assertion.

Assisted-by: Claude Code
Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

flaky: test_external_cancellation_acomplete_raise_once failed once in merge-queue CI (3.13)

1 participant