Skip to content

WSGI: later stream messages don't see context vars set around the call #462

Open

Description

@stefanvanburen

For WSGI server-streaming and bidi RPCs, the first response message is produced inside __call__, but later messages (and metadata interceptors' on_end) run while the app server iterates the response, after __call__ returns. So context vars that middleware sets and resets around the call (token = var.set(...) / finally: var.reset(token)) are visible for the first message and gone for the rest; a handler doing var.get() per message sees the value once and then a LookupError.

Came up while documenting auth middleware in connectrpc/connectrpc.com#450, which works around it by not resetting the var in the WSGI example.

Have a fix on svanburen/wsgi-stream-context: copy the context when _handle_stream returns the lazy response stream, and run each next() and the final close() in it. The regression test fails without it and passes with it, and poe check plus the sync conformance runs (gunicorn, pyvoy) pass. Overhead is ~95ns per streamed message.

It's a behavior change in edge cases, so probably worth a look before a PR: a var set only while the server iterates the response (not during __call__) won't be seen by later messages anymore, and vars the handler sets during iteration no longer leak out to the server's context. OTel's WSGI middleware re-enters its span during iteration, so I think it's unaffected.

(The alternative is leaving connect-py alone and documenting that WSGI middleware should restore its context during iteration, like OTel does.)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions