Skip to content

AI junk - #6130

Closed
waterWang wants to merge 1 commit into
pallets:mainfrom
waterWang:fix/stream-with-context-cross-thread-6123
Closed

AI junk#6130
waterWang wants to merge 1 commit into
pallets:mainfrom
waterWang:fix/stream-with-context-cross-thread-6123

Conversation

@waterWang

Copy link
Copy Markdown

Description

When a client disconnects mid-stream, the WSGI server abandons the body
iterator. The generator is later finalized by the garbage collector, often
on a different thread than the one that pushed the context.

ctx.pop() raises RuntimeError because _cv_app.get(None) returns None
on the GC thread. The context stays "stuck" on the original worker thread,
and teardown_appcontext never fires for subsequent requests on that thread.

Fix

Replace with ctx: with manual ctx.push() / ctx.pop() in the
stream_with_context generator. Wrap pop() in a try/except that catches
RuntimeError and resets the context state (_push_count and _cv_token)
to prevent thread pool poisoning.

Related

Closes #6123

When a client disconnects mid-stream, the WSGI server abandons the
body iterator. The generator is finalized by the garbage collector,
often on a different thread than the one that pushed the context.
ctx.pop() raises RuntimeError because the context is not active
on the GC thread, leaving the context stuck on the original thread.

Replace `with ctx:` with manual push()/pop() in the generator, and
catch the RuntimeError from cross-thread pop() to properly reset
the context state (_push_count and _cv_token).

Fixes pallets#6123
@davidism

Copy link
Copy Markdown
Member

@davidism davidism closed this Aug 10, 2026
@davidism davidism changed the title fix: prevent context leak in stream_with_context on cross-thread GC AI junk Aug 10, 2026
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.

stream_with_context: abandoned generator leaves the app context current on the worker thread; later requests skip teardown_appcontext

2 participants