Skip to content

asgiref backward compatibility #1305

@tony

Description

@tony

Checklist

  • The bug is reproducible against the latest release or master.
  • There are no similar issues or pull requests to fix it yet.

Describe the bug

Hi, thank you for the project, this is a shot in the dark since it's not a channels bug!

#1100 pinned the asgiref dependency to >=3.4.0 for mypy purposes. It may be worth loosening it if it's only mypy as the restriction requires the user to use asgiref 3.4.0, which triggers a well-known but unsolved channels (a different package)

Alternatives to pulling in asgiref for typings:

  1. Dropping the asgiref dependency and copying asgiref.typings to _types

    _types can have compat-like functionality depending on the asgiref version installed so things so uvicorn can be independent of django and channels.

  2. Loosening the constraint

    Would mypy work if try/catch with ImportError was used? Would be willing to consider it as a compatibility workaround until ASGIRef 3.4.1 + Channels 3.0.3 causes non-deterministic 500 errors serving static files django/channels#1722 is resolved?

    try:
        from asgiref.typing import WebSocketScope
    except ImportError:
       from asgiref.typing import WebsocketScope
       WebSocketScope = WebsocketScope

A word of note:

This is for posterity, of course it's never needed for an independent project such as uvicorn to change it's pinning due to another package's issues, but noteworthy since channels is often used alongside uvicorn by users.

The reasons why I post this here is channel's bug at django/channels#1722 is prominent, its easiest apparent workaround is to decrease asgiref's version below <3.4.0, and the only reason I can see 3.4.0 was pinned in #1100 is mypy and there may be a way to satisfy mypy and relax the constraint.

I think it's up to the maintainer and I wanted to document the issue.

Steps to reproduce the bug

I believe this happens on sites where static files are served via the asgi server. This happens when there's a heavy load (such as selenium tests).

Expected behavior

Static files via dev servers should serve without raising deadlock errors

Actual behavior

No response

Debugging material

Assuming uvicode 0.16.0, it requires we use asgiref 3.4.0+

Error: 1-03 17:27:52 +0000] [9] [ERROR] Exception in ASGI application
Traceback (most recent call last):
  File "/opt/venv/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 376, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "/opt/venv/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
    return await self.app(scope, receive, send)
  File "/opt/venv/lib/python3.10/site-packages/uvicorn/middleware/asgi2.py", line 17, in __call__
    await instance(receive, send)
  File "/opt/venv/lib/python3.10/site-packages/channels/http.py", line 192, in __call__
    await self.handle(body_stream)
  File "/opt/venv/lib/python3.10/site-packages/asgiref/sync.py", line 409, in __call__
    raise RuntimeError(
RuntimeError: Single thread executor already being used, would deadlock

Environment

OS: Ubuntu latest via docker
uvicorn: 0.16.0
channels: 2.4.0
asgiref: 3.4.0 (breakage) 3.3.4 (works)
python 3.10

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions