Экземпляры фонового рабочего канала Django - PullRequest
0 голосов
/ 02 мая 2018

Я работаю над проектом Django Channels-2 , где канальный слой используется для выгрузки информации из браузеров в потребитель, который анализирует его и отправляет результаты обратно в браузеры с помощью механизма groups .

Данные поступают от pusher через pusher-client и, следовательно, одинаковы для многих клиентских браузеров. Первым делом я настроил следующую инфраструктуру:

макет 1:
( browser1: Pusher-клиент, веб-сокет; ... browserN: Pusher-клиент, websocket)
<---->
WebsocketConsumer (член группа ; отправляет на канал , получает от группа )
<---->
BackgroundWorker (прослушивает канал ; отправляет группу )

Этот макет работает нормально и избавляет от необходимости загружать мой сервер соединением-толкачом, которое предоставляется отдельным браузерам. Но это также означает, что я передаю несколько копий одного и того же события своему Рабочему. Я понимаю, что есть решения этой проблемы, но они показались мне немного неловкими. Кроме того, это подразумевает много JavaScript-в браузерах. Тем более, что для каждой вкладки браузера разрешено только одно соединение через веб-сокет, и мне нужно передавать все через один сокет. Поэтому сейчас я использую следующую настройку:

макет 2:
( browser1: websocket; ... browserN: websocket)
<---->
WebsocketConsumer (участник группы ) ; отправляет на канал , получает из группы )
<---->
BackgroundWorker ( пушер-клиент ; прослушивает канал ; отправляет группу )

В этом макете браузер уведомляет потребителей, что ему нужны результаты данных, и если фоновый работник еще не запущен, он порождается и запускает клиент-толкач, и при каждом полученном событии анализирует данные и отправляет результат в группа и, следовательно, обратно в браузеры. Все это работает очень хорошо и хорошо.

ВОПРОС:
Теперь, когда я бегу

./manage.py runworker *channel-name*

Рабочий потребитель не запускается, пока он на самом деле не нужен. И когда первое сообщение поступает на канал, который он прослушивает, оно запускается и входит в цикл обработки событий клиента-отправителя. Последующие вызовы не приводят к появлению дополнительных рабочих, как мне кажется, и у меня есть флаг, если пушер уже запущен, поэтому у меня только одно соединение с активным пушером.

Q1: Могу ли я рассчитывать на фонового потребителя, который останется в живых после его запуска, или есть тайм-аут или что-то, если в очереди канала нет нового сообщения для чтения?

Q2: Существует ли лучше / больше надежный макет для моих операций?

У меня была также версия внешнего сервера веб-сокетов, в которой активен пушер, и результаты были доступны, но я не видел, как элегантно интегрировать его в проект каналов django, хотя он отлично работает. Тем не менее, это лучший подход и использование unix-сокетов?

Большое спасибо за ваш вклад!

[РЕДАКТИРОВАТЬ 1]

В серии Channels-1.x я обнаружил запись в разделе часто задаваемых вопросов о том, что с приложением Django channel можно также осуществлять внешнюю связь через канальный слой напрямую. Так что этот подход я сейчас тестирую, и он прекрасно работает. Так что я сейчас так делаю. Поскольку оба Q1 и Q2 все еще действительны и представляют интерес для меня, я оставлю вопрос в силе.

Краткий обзор того, как это делается в данный момент для заинтересованных лиц, показан в оставшейся части редактирования:

External.py

from <proj-name>.asgi import channel_layer
from asgiref.sync import async_to_sync
import pysher
...
# External program logic #
...
# Channel layer communication -> send_group #
async_to_sync(channel_layer.group_send)(
        <group>,
        {
            'type': "<type>",
            'data': <dict>,
        }
    )

в файле asgi.py Проекта каналов Джанго

import os
import django
from channels.routing import get_default_application
from channels.layers import get_channel_layer

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "<proj-name>.settings")
django.setup()
application = get_default_application()

# || the important part for us || #
# vv                           vv #
channel_layer = get_channel_layer()

Я использую серию Django Channels 2.x, которая немного отличается от серии 1.x. Эта настройка полностью устраняет необходимость в фоновом работнике, разъединяет pusher и django и делает все немного проще.

...