Python: Finalize abandoned functional workflow streams without ContextVar leaks - #7798
Conversation
…tVar leaks Stop holding the run span and event-origin token across yields so breaking out of a streaming functional workflow no longer fails during GC.
There was a problem hiding this comment.
Pull request overview
Prevents ContextVar leaks when functional workflow streams are abandoned.
Changes:
- Uses unattached workflow spans with scoped activation.
- Builds framework events before yielding.
- Adds abandonment and span behavior tests.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
_functional.py |
Revises functional workflow tracing and event emission. |
_events.py |
Adds safe framework-event construction. |
observability.py |
Adds unattached workflow span creation. |
test_functional_workflow.py |
Adds stream-abandonment regression tests. |
test_observability.py |
Tests unattached span behavior. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Reset the run guard in the generator finally so a follow-up run after GC is allowed, and assert no OpenTelemetry detach errors plus nested-span parenting under workflow.run.
Evan Mattson (moonbox3)
left a comment
There was a problem hiding this comment.
Thanks for taking care of this.
|
Shivani . (@Shivani767) please fix the failing CI/CD checks |
Python Test Coverage Report •
Python Unit Test Overview
|
|||||||||||||||||||||||||||||||||||||||||||||
Resolve pyright reportUnusedFunction on _framework_event helpers and add span attribute subscript suppressions in the unattached workflow span test.
30f4006 to
20e4ad6
Compare
|
Thanks for the review and for flagging the CI failures, Evan Mattson (@moonbox3). I've pushed follow-up fixes to address the failing checks and the Copilot review feedback: CI / typing
Copilot review follow-ups
Unit tests were already passing; the blockers were the Package Checks and Test Typing Checks above. Could you please approve and run workflows when you have a moment? The fork PR workflows are currently waiting on maintainer approval. Branch: |
Motivation & Context
Abandoning a functional-workflow
ResponseStreammid-iteration (async for event in stream: break) is a normal HITL pattern, but the run generator held both the OpenTelemetry run span and_framework_event_origin()open acrossyield. Garbage-collecting the generator later injectsGeneratorExitfrom a differentContext, soContextVar.resetraises (Failed to detach context,async generator ignored GeneratorExit).Description & Review Guide
_run_corenow starts the run span unattached (start_workflow_span) and activates it only around_execute. Framework lifecycle events are built inside_framework_event()so the origin token is reset before each yield._framework_event_origin()also suppresses cross-contextresetfailures as a last line of defense.originremainsFRAMEWORK. Nested processing spans still parent under the run span during_execute. GraphWorkflow._run_coreis unchanged (same class of OTel attach-across-yield; can be a follow-up)._activate_spanaround_executeis enough for nested-span parenting without reintroducing the leak.Related Issue
Fixes #7787
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.