Каналы Django Redis Channel Layer открывает много соединений - PullRequest
0 голосов
/ 06 сентября 2018

Мы недавно портировали часть нашего приложения на каналы django, используя бэкэнд уровня канала redis. Часть нашей установки все еще работает на python2 в докере, поэтому мы используем redis pub / sub для отправки сообщений обратно клиенту. Глобальный слушатель ( вдохновленный этим потоком ) перехватывает все сообщения и распространяет их в систему каналов django. Пока все работает нормально, но я вижу много отладочных сообщений Creating tcp connection..., проходящих мимо. Вывод, представленный ниже, соответствует одному событию. Кажется, что и слушатель, и потребитель создают два соединения redis. У меня недостаточно знаний о базовом механизме, чтобы определить, является ли это ожидаемым поведением, поэтому я спрашиваю здесь Этого следовало ожидать?

Слушатель использует экземпляр глобального уровня канала:

# maps the publish type to a method name of the django channel consumer
PUBLISH_TYPE_EVENT_MAP = {
    'state_change': 'update_client_state',
    'message': 'notify_client',
}
channel_layer = layers.get_channel_layer()


class Command(BaseCommand):
    help = u'Opens a connection to Redis and listens for messages, ' \
           u'and then whenever it gets one, sends the message onto a channel ' \
           u'in the Django channel system'

    ...

    def broadcast_message(self, msg_body):
        group_name = msg_body['subgrid_id'].replace(':', '_')
        try:
            event_name = PUBLISH_TYPE_EVENT_MAP[msg_body['publish_type']]
        # backwards compatibility
        except KeyError:
            event_name = PUBLISH_TYPE_EVENT_MAP[msg_body['type']]

        async_to_sync(channel_layer.group_send)(
            group_name, {
                "type": event_name,
                "kwargs": msg_body.get('kwargs'),
            })

Потребитель JsonWebsocketConsumer, который инициализируется следующим образом:

class SimulationConsumer(JsonWebsocketConsumer):

    def connect(self):
        """
        Establishes the connection with the websocket.
        """
        logger.debug('Incoming connection...')
        # subgrid_id can be set dynamically, see property subgrid_id
        self._subgrid_id = self.scope['url_route']['kwargs']['subgrid_id']
        async_to_sync(self.channel_layer.group_add)(
            self.group_name,
            self.channel_name
        )
        self.accept()

И метод, который вызывается из слушателя:

def update_client_state(self, event):
    """
    Public facing method that pushes the state of a simulation back
    to the client(s). Has to be called through django channels
    ```async_to_sync(channel_layer.group_send)...``` method
    """
    logger.debug('update_client_state event %s', event)
    current_state = self.redis_controller.fetch_state()
    data = {'sim_state': {
        'sender_sessid': self.session_id,
        'state_data': current_state}
    }
    self.send_json(content=data)

Одно событие дает мне этот вывод

listener_1              | DEBUG !! data    {'publish_type': 'state_change', 'subgrid_id': 'subgrid:6d1624b07e1346d5907bbd72869c00e8'}
listener_1              | DEBUG !! event_name    update_client_state
listener_1              | DEBUG !! kwargs    None
listener_1              | DEBUG !! group_name    subgrid_6d1624b07e1346d5907bbd72869c00e8
listener_1              | DEBUG Using selector: EpollSelector
listener_1              | DEBUG Parsing Redis URI 'redis://:@redis-threedi-server:6379/13'
listener_1              | DEBUG Creating tcp connection to ('redis-threedi-server', 6379)
listener_1              | DEBUG Parsing Redis URI 'redis://:@redis-threedi-server:6379/13'
listener_1              | DEBUG Creating tcp connection to ('redis-threedi-server', 6379)
threedi-server_1        | DEBUG Parsing Redis URI 'redis://:@redis-threedi-server:6379/13'
threedi-server_1        | DEBUG Creating tcp connection to ('redis-threedi-server', 6379)
threedi-server_1        | DEBUG update_client_state event {'type': 'update_client_state', 'kwargs': None}
threedi-server_1        | DEBUG Parsing Redis URI 'redis://:@redis-threedi-server:6379/13'
threedi-server_1        | DEBUG Creating tcp connection to ('redis-threedi-server', 6379)
...