Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve execution context when running code in ThreadPool #31

Merged
merged 2 commits into from
Dec 26, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion a2wsgi/wsgi.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import asyncio
import collections
import functools
import os
import sys
import typing
from concurrent.futures import ThreadPoolExecutor

from .types import Environ, Message, Receive, Scope, Send, StartResponse, WSGIApp

try:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new version of a2wsgi only supports above 3.7, so we can use contextvars directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, didn't know that.
I checked the pyproject.toml which still includes 3.6.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that was an oversight on my part.

# Python 3.7+
import contextvars
except ImportError:
contextvars = None


class Body:
def __init__(self, loop: asyncio.AbstractEventLoop, receive: Receive) -> None:
Expand Down Expand Up @@ -184,8 +191,13 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
sender = None
try:
sender = self.loop.create_task(self.sender(send))
if contextvars is not None:
context = contextvars.copy_context()
func = functools.partial(context.run, self.wsgi)
else:
func = self.wsgi
await self.loop.run_in_executor(
self.executor, self.wsgi, environ, self.start_response
self.executor, func, environ, self.start_response
)
self.send_queue.append(None)
self.send_event.set()
Expand Down