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

ASGI flow error using websockets #414

Closed
estyrke opened this issue Oct 14, 2024 · 10 comments · Fixed by #416
Closed

ASGI flow error using websockets #414

estyrke opened this issue Oct 14, 2024 · 10 comments · Fixed by #416
Labels
asgi Issue related to ASGI protocol bug Something isn't working
Milestone

Comments

@estyrke
Copy link

estyrke commented Oct 14, 2024

I get this error using FastAPI with granian (possibly related to #186). Repro:

import granian
from fastapi import FastAPI
from granian.constants import Interfaces

app = FastAPI()


def run():
    granian.Granian(
        target=f"{__name__}:app",
        address="0.0.0.0",
        port=8000,
        interface=Interfaces.ASGI,
    ).serve()


if __name__ == "__main__":
    run()

Then just new WebSocket("ws://localhost:8000").connect in a browser console will trigger this error:

[ERROR] Application callable raised an exception
Traceback (most recent call last):
  File "/.venv/lib/python3.12/site-packages/granian/_futures.py", line 4, in future_watcher
    await inner(watcher.scope, watcher.proto)
  File "/.venv/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "/.venv/lib/python3.12/site-packages/starlette/applications.py", line 113, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 152, in __call__
    await self.app(scope, receive, send)
  File "/.venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 62, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 62, in wrapped_app
    raise exc
  File "/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 51, in wrapped_app
    await app(scope, receive, sender)
  File "/.venv/lib/python3.12/site-packages/starlette/routing.py", line 715, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/.venv/lib/python3.12/site-packages/starlette/routing.py", line 765, in app
    await self.default(scope, receive, send)
  File "/.venv/lib/python3.12/site-packages/starlette/routing.py", line 644, in not_found
    await websocket_close(scope, receive, send)
  File "/.venv/lib/python3.12/site-packages/starlette/websockets.py", line 195, in __call__
    await send({"type": "websocket.close", "code": self.code, "reason": self.reason})
  File "/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 48, in sender
    await send(message)
RuntimeError: ASGI flow error

Granian 1.6.0, FastAPI 0.115.2.

@estyrke
Copy link
Author

estyrke commented Oct 14, 2024

I tried with uvicorn too, there I get a 403 response: INFO: ('127.0.0.1', 49425) - "WebSocket /" 403

It seems it has special handling when it gets "websocket.close" when the handshake is not completed.

@estyrke
Copy link
Author

estyrke commented Oct 14, 2024

I should add that our application doesn't use websockets at all, and we have no code to handle websocket requests. We just noticed this crash, probably from some botnet trying to probe us.

@gi0baro gi0baro added bug Something isn't working asgi Issue related to ASGI protocol labels Oct 14, 2024
@gi0baro gi0baro added this to the 1.6 milestone Oct 14, 2024
@gi0baro
Copy link
Member

gi0baro commented Oct 14, 2024

@estyrke thank you for reporting thing. Gonna push a fix ASAP and include it in 1.6.1

@Tragio
Copy link

Tragio commented Oct 14, 2024

2024-10-13 18:02:37.467 | RuntimeError: ASGI flow error |  
-- | -- | --
  |   | 2024-10-13 18:02:37.467 | ^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:37.467 | result = task.result() |  
  |   | 2024-10-13 18:02:37.467 | File "/usr/local/lib/python3.12/site-packages/channels/utils.py", line 49, in await_many_dispatch |  
  |   | 2024-10-13 18:02:37.467 | await task |  
  |   | 2024-10-13 18:02:37.467 | File "/usr/local/lib/python3.12/site-packages/channels/utils.py", line 57, in await_many_dispatch |  
  |   | 2024-10-13 18:02:37.467 | await await_many_dispatch( |  
  |   | 2024-10-13 18:02:37.467 | File "/usr/local/lib/python3.12/site-packages/channels/consumer.py", line 58, in __call__ |  
  |   | 2024-10-13 18:02:37.467 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:37.467 | return await consumer(scope, receive, send) |  
  |   | 2024-10-13 18:02:37.467 | File "/usr/local/lib/python3.12/site-packages/channels/consumer.py", line 94, in app |  
  |   | 2024-10-13 18:02:37.467 | ^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:37.467 | return await application( |  
  |   | 2024-10-13 18:02:37.467 | File "/usr/local/lib/python3.12/site-packages/channels/routing.py", line 132, in __call__ |  
  |   | 2024-10-13 18:02:37.467 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:37.467 | return await self.inner(scope, receive, send) |  
  |   | 2024-10-13 18:02:37.467 | File "/usr/local/lib/python3.12/site-packages/channels/middleware.py", line 24, in __call__ |  
  |   | 2024-10-13 18:02:37.467 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:37.467 | return await super().__call__(scope, receive, send) |  
  |   | 2024-10-13 18:02:37.467 | File "/usr/local/lib/python3.12/site-packages/channels/auth.py", line 185, in __call__ |  
  |   | 2024-10-13 18:02:37.467 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:37.467 | return await self.inner(wrapper.scope, receive, wrapper.send) |  
  |   | 2024-10-13 18:02:37.467 | File "/usr/local/lib/python3.12/site-packages/channels/sessions.py", line 263, in __call__ |  
  |   | 2024-10-13 18:02:37.467 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:37.467 | return await self.inner(dict(scope, cookies=cookies), receive, send) |  
  |   | 2024-10-13 18:02:37.467 | File "/usr/local/lib/python3.12/site-packages/channels/sessions.py", line 47, in __call__ |  
  |   | 2024-10-13 18:02:37.467 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:37.467 | return await self.application(scope, receive, send) |  
  |   | 2024-10-13 18:02:37.467 | File "/usr/local/lib/python3.12/site-packages/channels/security/websocket.py", line 37, in __call__ |  
  |   | 2024-10-13 18:02:37.467 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:37.467 | return await application(scope, receive, send) |  
  |   | 2024-10-13 18:02:37.467 | File "/usr/local/lib/python3.12/site-packages/channels/routing.py", line 62, in __call__ |  
  |   | 2024-10-13 18:02:37.467 | await inner(watcher.scope, watcher.proto) |  
  |   | 2024-10-13 18:02:37.467 | File "/usr/local/lib/python3.12/site-packages/granian/_futures.py", line 4, in future_watcher |  
  |   | 2024-10-13 18:02:37.467 | Traceback (most recent call last): |  
  |   | 2024-10-13 18:02:37.467 | [ERROR] Application callable raised an exception |  
  |   | 2024-10-13 18:02:23.466 | RuntimeError: ASGI flow error |  
  |   | 2024-10-13 18:02:23.466 | ^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:23.466 | result = task.result() |  
  |   | 2024-10-13 18:02:23.466 | File "/usr/local/lib/python3.12/site-packages/channels/utils.py", line 49, in await_many_dispatch |  
  |   | 2024-10-13 18:02:23.466 | await task |  
  |   | 2024-10-13 18:02:23.466 | File "/usr/local/lib/python3.12/site-packages/channels/utils.py", line 57, in await_many_dispatch |  
  |   | 2024-10-13 18:02:23.466 | await await_many_dispatch( |  
  |   | 2024-10-13 18:02:23.466 | File "/usr/local/lib/python3.12/site-packages/channels/consumer.py", line 58, in __call__ |  
  |   | 2024-10-13 18:02:23.466 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:23.466 | return await consumer(scope, receive, send) |  
  |   | 2024-10-13 18:02:23.466 | File "/usr/local/lib/python3.12/site-packages/channels/consumer.py", line 94, in app |  
  |   | 2024-10-13 18:02:23.466 | ^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:23.466 | return await application( |  
  |   | 2024-10-13 18:02:23.466 | File "/usr/local/lib/python3.12/site-packages/channels/routing.py", line 132, in __call__ |  
  |   | 2024-10-13 18:02:23.466 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:23.466 | return await self.inner(scope, receive, send) |  
  |   | 2024-10-13 18:02:23.466 | File "/usr/local/lib/python3.12/site-packages/channels/middleware.py", line 24, in __call__ |  
  |   | 2024-10-13 18:02:23.466 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:23.466 | return await super().__call__(scope, receive, send) |  
  |   | 2024-10-13 18:02:23.466 | File "/usr/local/lib/python3.12/site-packages/channels/auth.py", line 185, in __call__ |  
  |   | 2024-10-13 18:02:23.466 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:23.466 | return await self.inner(wrapper.scope, receive, wrapper.send) |  
  |   | 2024-10-13 18:02:23.466 | File "/usr/local/lib/python3.12/site-packages/channels/sessions.py", line 263, in __call__ |  
  |   | 2024-10-13 18:02:23.466 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:23.466 | return await self.inner(dict(scope, cookies=cookies), receive, send) |  
  |   | 2024-10-13 18:02:23.466 | File "/usr/local/lib/python3.12/site-packages/channels/sessions.py", line 47, in __call__ |  
  |   | 2024-10-13 18:02:23.466 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:23.466 | return await self.application(scope, receive, send) |  
  |   | 2024-10-13 18:02:23.466 | File "/usr/local/lib/python3.12/site-packages/channels/security/websocket.py", line 37, in __call__ |  
  |   | 2024-10-13 18:02:23.466 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |  
  |   | 2024-10-13 18:02:23.466 | return await application(scope, receive, send) |  
  |   | 2024-10-13 18:02:23.466 | File "/usr/local/lib/python3.12/site-packages/channels/routing.py", line 62, in __call__ |  
  |   | 2024-10-13 18:02:23.466 | await inner(watcher.scope, watcher.proto) |  
  |   | 2024-10-13 18:02:23.466 | File "/usr/local/lib/python3.12/site-packages/granian/_futures.py", line 4, in future_watcher |  
  |   | 2024-10-13 18:02:23.466 | Traceback (most recent call last): |  
  |   | 2024-10-13 18:02:23.466 | [ERROR] Application callable raised an exception

Not sure if this is related @gi0baro, however, I have this Application callable raised an exception with frequency on Sentry. But in my case, I'm using Django and Django Channels 🤔

@grant-oscillolabs
Copy link

Very timely as I was looking into these errors today for our platform:

  • Django 5.1.2
  • Channels 4.1.0
  • Granian 1.6.0

We are using websockets (purely for pushing notifications), but the flow error happens randomly and I don't have any ideas currently on how to debug it effectively. It doesn't appear to be impacting performance/useability (nothing reported anyway), but it'd be good to understand more about it.

2024-10-14T00:10:37.621926524Z [ERROR] Application callable raised an exception
2024-10-14T00:10:37.621976725Z Traceback (most recent call last):
2024-10-14T00:10:37.621985425Z   File "/usr/local/lib/python3.12/site-packages/granian/_futures.py", line 4, in future_watcher
2024-10-14T00:10:37.621992626Z     await inner(watcher.scope, watcher.proto)
2024-10-14T00:10:37.621998626Z   File "/usr/local/lib/python3.12/site-packages/channels/routing.py", line 62, in __call__
2024-10-14T00:10:37.622003926Z     return await application(scope, receive, send)
2024-10-14T00:10:37.622008926Z            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-10-14T00:10:37.622013726Z   File "/usr/local/lib/python3.12/site-packages/channels/security/websocket.py", line 37, in __call__
2024-10-14T00:10:37.622019426Z     return await self.application(scope, receive, send)
2024-10-14T00:10:37.622025026Z            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-10-14T00:10:37.622030226Z   File "/usr/local/lib/python3.12/site-packages/channels/sessions.py", line 47, in __call__
2024-10-14T00:10:37.622035426Z     return await self.inner(dict(scope, cookies=cookies), receive, send)
2024-10-14T00:10:37.622057427Z            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-10-14T00:10:37.622063227Z   File "/usr/local/lib/python3.12/site-packages/channels/sessions.py", line 263, in __call__
2024-10-14T00:10:37.622069627Z     return await self.inner(wrapper.scope, receive, wrapper.send)
2024-10-14T00:10:37.622075227Z            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-10-14T00:10:37.622079927Z   File "/usr/local/lib/python3.12/site-packages/channels/auth.py", line 185, in __call__
2024-10-14T00:10:37.622085327Z     return await super().__call__(scope, receive, send)
2024-10-14T00:10:37.622090527Z            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-10-14T00:10:37.622095527Z   File "/usr/local/lib/python3.12/site-packages/channels/middleware.py", line 24, in __call__
2024-10-14T00:10:37.622100927Z     return await self.inner(scope, receive, send)
2024-10-14T00:10:37.622105528Z            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-10-14T00:10:37.622109928Z   File "/usr/local/lib/python3.12/site-packages/channels/routing.py", line 132, in __call__
2024-10-14T00:10:37.622114728Z     return await application(
2024-10-14T00:10:37.622119828Z            ^^^^^^^^^^^^^^^^^^
2024-10-14T00:10:37.622125328Z   File "/usr/local/lib/python3.12/site-packages/channels/consumer.py", line 94, in app
2024-10-14T00:10:37.622130828Z     return await consumer(scope, receive, send)
2024-10-14T00:10:37.622135728Z            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-10-14T00:10:37.622140728Z   File "/usr/local/lib/python3.12/site-packages/channels/consumer.py", line 58, in __call__
2024-10-14T00:10:37.622146028Z     await await_many_dispatch(
2024-10-14T00:10:37.622151828Z   File "/usr/local/lib/python3.12/site-packages/channels/utils.py", line 57, in await_many_dispatch
2024-10-14T00:10:37.622157129Z     await task
2024-10-14T00:10:37.622161929Z   File "/usr/local/lib/python3.12/site-packages/channels/utils.py", line 49, in await_many_dispatch
2024-10-14T00:10:37.622167229Z     result = task.result()
2024-10-14T00:10:37.622172129Z              ^^^^^^^^^^^^^
2024-10-14T00:10:37.622177029Z RuntimeError: ASGI flow error

@gi0baro
Copy link
Member

gi0baro commented Oct 15, 2024

@Tragio @grant-oscillolabs it is quite hard for me to debug the almost cryptic stack traces of Django channels.
It might be related to the OP or not; probably the best approach is to fix the original issue from the OP and let you check if that also covers your case. If not, then feel free to open a dedicated issue.

@xeroticikot
Copy link

I'm facing the same scenario with latest django & channel websocket implementation. On frontend, the connection gets open, but instantly gets closed. On the console getting the "RuntimeError: ASGI flow error". BTW, the setup works on development but fails on production.

@Tragio
Copy link

Tragio commented Dec 2, 2024

@grant-oscillolabs did the new version solve the issue for you?

Traceback (most recent call last):
  File "/app/.venv/lib/python3.12/site-packages/granian/_futures.py", line 4, in future_watcher
    await inner(watcher.scope, watcher.proto)
  File "/app/.venv/lib/python3.12/site-packages/channels/routing.py", line 48, in __call__
    return await application(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/security/websocket.py", line 37, in __call__
    return await self.application(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/sessions.py", line 44, in __call__
    return await self.inner(dict(scope, cookies=cookies), receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/sessions.py", line 261, in __call__
    return await self.inner(wrapper.scope, receive, wrapper.send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/auth.py", line 185, in __call__
    return await super().__call__(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/middleware.py", line 24, in __call__
    return await self.inner(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/routing.py", line 118, in __call__
    return await application(
           ^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/consumer.py", line 95, in app
    return await consumer(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/consumer.py", line 58, in __call__
    await await_many_dispatch(
  File "/app/.venv/lib/python3.12/site-packages/channels/utils.py", line 57, in await_many_dispatch
    await task
  File "/app/.venv/lib/python3.12/site-packages/channels/utils.py", line 49, in await_many_dispatch
    result = task.result()
             ^^^^^^^^^^^^^
RuntimeError: ASGI flow error

I don't see a problem in functionality but I still have this error occasionally.

@gi0baro
Copy link
Member

gi0baro commented Dec 6, 2024

@xeroticikot @Tragio ASGI flow error is thrown by Granian every time the application sends an ASGI message to the server which is unexpected given the current protocol state (eg: sending more body after stating no more body was intended to be sent, accepting a websocket multiple times, sending messages on a closed socket, etc).

In order to fully debug this, it would be nice to have the ASGI message content sent by Django channels to Granian, otherwise it's very difficult to make assumptions on correct/incorrect behavior of the involved parts.

The actual root cause for the OP is fixed; also 1.7 will change the way Granian interacts with asyncio primitives, so if anything is somehow weird in contrast with what Django expects, it might be worth checking if the new version solves issues in that regards.

@grant-oscillolabs
Copy link

@grant-oscillolabs did the new version solve the issue for you?

Traceback (most recent call last):
  File "/app/.venv/lib/python3.12/site-packages/granian/_futures.py", line 4, in future_watcher
    await inner(watcher.scope, watcher.proto)
  File "/app/.venv/lib/python3.12/site-packages/channels/routing.py", line 48, in __call__
    return await application(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/security/websocket.py", line 37, in __call__
    return await self.application(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/sessions.py", line 44, in __call__
    return await self.inner(dict(scope, cookies=cookies), receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/sessions.py", line 261, in __call__
    return await self.inner(wrapper.scope, receive, wrapper.send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/auth.py", line 185, in __call__
    return await super().__call__(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/middleware.py", line 24, in __call__
    return await self.inner(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/routing.py", line 118, in __call__
    return await application(
           ^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/consumer.py", line 95, in app
    return await consumer(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/channels/consumer.py", line 58, in __call__
    await await_many_dispatch(
  File "/app/.venv/lib/python3.12/site-packages/channels/utils.py", line 57, in await_many_dispatch
    await task
  File "/app/.venv/lib/python3.12/site-packages/channels/utils.py", line 49, in await_many_dispatch
    result = task.result()
             ^^^^^^^^^^^^^
RuntimeError: ASGI flow error

I don't see a problem in functionality but I still have this error occasionally.

Sorry for the late reply on this one! Log errors still persisted after updating to 1.6.1, but again no real issues in terms of functionality. I'll update Granian to 1.7 when released and keep monitoring

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
asgi Issue related to ASGI protocol bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants