-
-
Notifications
You must be signed in to change notification settings - Fork 952
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
Allow background tasks to run with custom BaseHTTPMiddleware
's
#1441
Changes from all commits
149aa7c
e161bae
e1af17b
3011702
20406e7
8e6063d
5843a57
346f893
470b31c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -24,9 +24,11 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: | |||||||||||||||||||||||||
await self.app(scope, receive, send) | ||||||||||||||||||||||||||
return | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
call_next_response = None | ||||||||||||||||||||||||||
send_stream, recv_stream = anyio.create_memory_object_stream() | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
async def call_next(request: Request) -> Response: | ||||||||||||||||||||||||||
app_exc: typing.Optional[Exception] = None | ||||||||||||||||||||||||||
send_stream, recv_stream = anyio.create_memory_object_stream() | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
async def coro() -> None: | ||||||||||||||||||||||||||
nonlocal app_exc | ||||||||||||||||||||||||||
|
@@ -61,17 +63,22 @@ async def body_stream() -> typing.AsyncGenerator[bytes, None]: | |||||||||||||||||||||||||
if app_exc is not None: | ||||||||||||||||||||||||||
raise app_exc | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
response = StreamingResponse( | ||||||||||||||||||||||||||
nonlocal call_next_response | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
call_next_response = StreamingResponse( | ||||||||||||||||||||||||||
status_code=message["status"], content=body_stream() | ||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||
response.raw_headers = message["headers"] | ||||||||||||||||||||||||||
return response | ||||||||||||||||||||||||||
call_next_response.raw_headers = message["headers"] | ||||||||||||||||||||||||||
return call_next_response | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
async with anyio.create_task_group() as task_group: | ||||||||||||||||||||||||||
request = Request(scope, receive=receive) | ||||||||||||||||||||||||||
response = await self.dispatch_func(request, call_next) | ||||||||||||||||||||||||||
if call_next_response and response is not call_next_response: | ||||||||||||||||||||||||||
async with recv_stream: | ||||||||||||||||||||||||||
async for _ in recv_stream: | ||||||||||||||||||||||||||
... # pragma: no cover | ||||||||||||||||||||||||||
await response(scope, receive, send) | ||||||||||||||||||||||||||
Comment on lines
+77
to
81
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems to me that we will wait for Of course, I do not know the relevant technologies (ASGI/the server implementations/Starlette) as well as you do, so there could very well be a reason that either my analysis is wrong, or that my suggestions are unworkable.
Suggested change
|
||||||||||||||||||||||||||
task_group.cancel_scope.cancel() | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
async def dispatch( | ||||||||||||||||||||||||||
self, request: Request, call_next: RequestResponseEndpoint | ||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can create a function that performs this logic, if wanted.