Monday, January 16, 2017

Re: Django Channels: send message on Group from worker process

Hi Joren,

This is a deliberate design decision; consumers (the things you have in views.py) are meant to not block and return immediately. Any blocking action, including delaying, needs to be done outside of the consumer and then send a message to invoke the next logic needed.

This is because Channels does not make the Django parts asynchronous internally; all of the async stuff is down to the Daphne code and the overall system design. By sleeping for 5 seconds you are locking up an entire worker thread for 5 seconds; you could easily run out of workers this way.

If you want to delay a message being sent (or run code after a delay - just make a new channel for it and delay a message to that channel), you can use the new built-in channels Delay Server, which is fully asynchronous code and so can handle delaying thousands of messages a second in one process: http://channels.readthedocs.io/en/latest/delay.html

Andrew

On Mon, Jan 16, 2017 at 12:31 PM, Joren Inghelbrecht <inghelbrecht.joren@gmail.com> wrote:

Hi everyone,


The idea is to run a background task on the worker.connect worker. While executing the task, I would like to send its progress to a connected client via the notifications Group.


The problem: the messages sent to the notifications Group are delayed until the task on the worker is finished. So: both messages 'Start' and 'Stop' appear simultaneously on the client, after a delay of 5 seconds (sleep(5)). I would expect the message 'Start', followed by a 5sec delay, followed by the message 'Stop'. Any idea why this is not the case?


I have the following three processes running:

  • daphne tests.asgi:channel_layer
  • python manage.py runworker --exclude-channel=worker.connect
  • python manage.py runworker --only-channel=worker.connect

In views.py:


def run(request, pk):      Channel('worker.connect').send({'pk': pk})      return HttpResponse(status=200)


In consumers.py:


def ws_connect(message):
    Group('notifications').add(message.reply_channel)      message.reply_channel.send({"accept": True})    def worker_connect(message):      run_channel(message)


In views.py:


def run_channel(message):      Group('notifications').send({'text': 'Start'})      sleep(5)      Group('notifications').send({'text': 'Stop'})

routing.py


channel_routing = {      'websocket.connect': consumers.ws_connect,      'worker.connect': consumers.worker_connect,  }


Thank you in advance!

Kind regards,

Joren Inghelbrecht

--
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-users@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/92b30e17-ebaa-4121-b5cf-7fc8c657498c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
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-users@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/CAFwN1urBBj61SHqU9FSNWwy8%2BTC_F6vvFJ9zWbreFKG%2BoD-0Xg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment