Opened 4 days ago

Last modified 2 days ago

#36281 new Cleanup/optimization

ASGIHandler perfoms sync writes when reading the chunks of a HTTP response's body

Reported by: Brian Atkinson Owned by:
Component: HTTP handling Version: dev
Severity: Normal Keywords: asgi async
Cc: Carlton Gibson Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no
Pull Requests:How to create a pull request

Description

See https://github.com/django/django/blob/c1a4fccf53437e480c42648f67277fb7e63ed4ab/django/core/handlers/asgi.py#L266

That write may end up resulting in IO actually hitting disk. This could result in the async loop stalling if the underlying write call is slow.

According to the ticket's flags, the next step(s) to move this issue forward are:

  • To provide a patch by sending a pull request. Claim the ticket when you start working so that someone else doesn't duplicate effort. Before sending a pull request, review your work against the patch review checklist. Check the "Has patch" flag on the ticket after sending a pull request and include a link to the pull request in the ticket comment when making that update. The usual format is: [https://github.com/django/django/pull/#### PR].

Change History (4)

comment:1 by Rayyan Khan, 3 days ago

I think you're right, the sync write in this async code path might cause problems if the disk I/O is slow. Maybe we could wrap the body_file.write call with sync_to_async to prevent blocking the event loop?

comment:2 by Natalia Bidart, 2 days ago

Cc: Carlton Gibson added
Component: UncategorizedHTTP handling
Keywords: asgi async added
Triage Stage: UnreviewedAccepted
Type: UncategorizedCleanup/optimization
Version: 5.1dev

Thank you Brian for the report! I agree that this is worth addressing, as disk IO can indeed lead to stalls.

Careful consideration will be needed for how to handle the chunked file writing without blocking the event loop. I'm wondering if we should have a sort of abstraction for the chunked file writer and allow people to override. Depending on the project's constraints or current dependencies, some projects may choose to use a 3rd party library like asynctempfile (unclear whether this is currently maintained), or Django channels, or something else?

We're open to a patch that addresses this while ensuring compatibility and avoiding unintended regressions. Would you like to work on this?

(I'm torn whether to categorize this as Cleanup or New Feature, for now I'm going with the former but we can adjust later on.)

comment:3 by Natalia Bidart, 2 days ago

Summary: Sync write in async code pathASGIHandler perfoms sync writes when reading the chunks of a HTTP response's body

comment:4 by Carlton Gibson, 2 days ago

That's a good one. Yes. A consideration for being careful about allowed body sizes under ASGI. It'd be interesting to see what other ASGI frameworks do here.

…use a 3rd party library like ​asynctempfile (unclear whether this is currently maintained)…

It looks small and depends on aiofiles which is a package I'd trust. It could likely be vendored if needed, perhaps using the async version if aiofiles was available.

(I'd have to think through the severity of the blocking I/O to say whether using such would be recommended or even required. We already mention aiofiles in the docs, e.g. FileResponses.)

Note: See TracTickets for help on using tickets.
Back to Top