AsyncHttpConsumer regression and disconnect handling
See original GitHub issueHi folks,
I just discovered Channels >=2.1.6 introduced an incompatibility with the django-eventstream library. Client requests hang, due to what I believe is the consumer task ending too quickly.
Our library implements handle
, which returns quickly and spawns a subtask to handle the ongoing stream. At the time the code was written, my understanding was that spawning a task was the proper way to handle streaming responses as it allowed the original task to keep running in order to detect disconnects.
However, as of commit a2561396cd3a508c8475211cbe7b1618985c1eb9, disconnect
is called immediately after handle
returns. This breaks spawn-style streaming implementations.
I’m attempting to adjust our code to work with the latest Channels behavior, essentially by not spawning a task (just run the streaming logic within handle
without returning), but now I run into the problem that I can’t cleanly handle disconnects. Instead, after the client disconnects, the task is eventually killed:
Application instance <Task pending coro=<SessionMiddlewareInstance.__call__() running at /home/justin/dev/django-eventstream/examples/chat2/venv/lib/python3.6/site-packages/channels/sessions.py:179> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x7fafd82f6ac8>()]>> for connection <WebRequest at 0x7fafd934e9b0 method=GET uri=/rooms/default/events/ clientproto=HTTP/1.1> took too long to shut down and was killed.
Unfortunately this doesn’t give the task a chance to clean up properly.
This issue is also oddly familiar: #1051
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (5 by maintainers)
Okay here we go: #1250
Hey @jkarneges. What I was initially interested in is exactly what changed. i.e. a test (for your use-case) that passes in 2.1.5 and fails in 2.1.6. It would help to be able to play with what you were doing.
I agree you’ve diagnosed the question here. Even if
handle()
does not return I’m expectinghttp_disconnect()
to receive thehttp.disconnect
event and call yourdisconnect()
method:https://github.com/django/channels/blob/a660d81899e1cfd030f20a499cdeae1cea3e0646/channels/generic/http.py#L87-L92