Manoj Datt
Manoj Datt

Reputation: 388

Django channel Error "took too long to shut down and was killed."

I am getting this error on my console log, and on form submit it keeps loading does not post data to the server.

/home/Python/Working/Benutzerverwaltung/env/lib/python3.6/site-packages/channels/sessions.py:183>
wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at
0x7fab9fe51408>()]>> for connection <WebSocketProtocol
client=['127.0.0.1', 59462] path=b'/ws/stream/Sales'> took too long to
shut down and was killed.

Here is my code for closing the channel.

async def disconnect(self, code):
    async_to_sync(self.channel_layer.group_discard)(
        self.room_group_name,
        self.channel
    )
    await self.close()

async def websocket_disconnect(self, event):
    print("Disconnect", event)
    await self.send({
        "type": "websocket.close"
    })

How to fix this?

Upvotes: 9

Views: 15102

Answers (3)

tolazytosignup
tolazytosignup

Reputation: 41

The documentation says the following:

Once you have finished doing your post-disconnect cleanup, you need to raise channels.exceptions.StopConsumer to halt the ASGI application cleanly and let the server clean it up. If you leave it running - by not raising this exception - the server will reach its application close timeout (which is 10 seconds by default in Daphne) and then kill your application and raise a warning. https://channels.readthedocs.io/en/latest/topics/consumers.html#closing-consumers

raising StopConsumer in the websocket_disconnect method fixed the issue for me.

Upvotes: 1

Muhammad Abbas
Muhammad Abbas

Reputation: 65

I solved this error. Try to delete your env and create a new one. The error will disappear.

Upvotes: -3

Ben Sturmfels
Ben Sturmfels

Reputation: 1483

This error is broadly because a coroutine is hanging around longer than it should.

This specific case

In this case, AsyncWebsocketConsumer.websocket_disconnect() is being overridden but is not calling super() which means that StopConsumer() isn't run (see channels/generic/websocket.py:228). Perhaps don't override websocket_disconnect at all, since there's nothing in this example that justifies it.

Also note that async_to_sync is intended for sync consumers, but this is an async consumer. Instead use:

await self.channel_layer.group_discard(
    self.room_group_name,
    self.channel
)

The await self.close() isn't required as disconnect has already occurred. Remove that line.

AsyncHttpConsumer

Similarly in an AsyncHttpConsumer the mistake I've often made is to call await self.send_response(...) but then forget to call return afterwards, so the function will continue on when you didn't expect it to.

AsyncHttpConsumer also has an open bug report about not surfacing exceptions within handle(). The only option currently is to adding extra print/logging lines to figure out what is/isn't running.

Beware of django-debug-toolbar

Also worth noting is that adding debug-toolbar to your INSTALLED_APPS will silence exceptions in your async consumers. See discussion here. Beware!

Upvotes: 10

Related Questions