Django Channels: Multiple 'send' calls in the same consumer

1,313 views
Skip to first unread message

Tristan Barry

unread,
May 13, 2017, 3:08:29 PM5/13/17
to Django users
Hi - I'm working with Django Channels (1.1.3) on a Django project and I have some questions about how to send multiple messages from the same consumer.

The idea is the consumer will receive a request to do some work, and will send incremental results back to user. I've attached a simplified example below with some questions. I'm hoping someone can steer me in the right direction.
 

Django Channels:

def do_some_work(message):
    for i in range(3):
        time.sleep(2)
        message.reply_channel.send({"text": 'Finished work ' + str(i)})

def ws_connect(message):
    message.reply_channel.send({"accept": True})

channel_routing = [
    route('websocket.connect', ws_connect),
    route('websocket.receive', do_some_work, path=r'/todo')
]

Javascript (borrowed mostly from the docs):

socket = new WebSocket("ws://" + window.location.host + "/todo/");
socket.onmessage = function(e) {
    console.log(e.data);
}
socket.onopen = function() {
    socket.send("hello world");
}
// Call onopen directly if socket is already open
if (socket.readyState == WebSocket.OPEN) socket.onopen();


Expected results: Every two seconds the browser would receive a reply from the consumer saying 'Finished work x'. 

What I observe is a delay for ~6 seconds and then all results returned at the same time. Are the response on the reply channel blocked somehow? Is there I way I can yield, or release the message before doing the next increment of work?

I've also tried setting up a new consumer that only replies via a Group. So instead of message.reply_channel.send, I would Channel('reply-channel').send({results: ...}) and have a new consumer defined on channel_routing for the 'reply-channel'. But the results are the same - all the 'work' is completed before the browser receives a response. 

Any hints on how to send multiple message in the same consumer?

Thanks in advance.

Andrew Godwin

unread,
May 13, 2017, 9:09:14 PM5/13/17
to django...@googlegroups.com
Hi Tristan,

All messages sent from a consumer are delayed for sending until the consumer exits to keep things atomic - long-running consumers is bad for performance, as they'll hog an entire thread (they run synchronously) and so you'll quickly run out of threads/processes as you'll end up using one per connection.

Instead, you should do your task and exit out of the consumer as quickly as possible to free the worker space for something else to run. To achieve repeated execution with delays, you can either look at the delay server (http://channels.readthedocs.io/en/stable/delay.html) or write your own consumer code that talks to channels that uses an asynchronous framework (asyncio, twisted)

Andrew

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/4bf7d2ce-9a13-4f85-9933-cb8496e1f59d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tristan Barry

unread,
May 16, 2017, 11:04:14 AM5/16/17
to Django users
Thank you very much for clarifying - I wasn't exactly sure how to approach this, but your response makes sense.

Cheers!
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.

djangorobert

unread,
May 16, 2017, 11:11:56 AM5/16/17
to Django users
Are you using this in production if so what service as in was or webfaction or azure u ask because I'm trying to use it but can't figure out what I'm doing wrong I'm using Andrew Godwin's multichat example from git hub
Reply all
Reply to author
Forward
0 new messages