Подготовка к обновлению OrbitX v1.3 день 2: Компромисс

Всем добрый день/вечер/ночь

Недавно я выкатил апдейт v1.2 для OrbitX(см. ссылку ниже) в котором рассказал о новых фичах которые добавил и о возможных багах, которые мне удалось уже заметить и начать с ними работать.

Самый главный и важный баг заключался в одном - Иногда при выборе большого количества спутников одновременно не все WebSocket открывают соединения из-за чего некоторые спутники могут не появиться/не отображать никакой информации.

Решение проблемы?

Я выдвинул два подхода, которые могли бы помочь решить данную проблему: 1. Мультиплексное динамическое соединение - у него возникает следующая проблема: каждый пользователь это один открытый WebSocket. А теперь представим - что будет если пользователей будет одновременно 1000? Правильно 1000 соединеный, что тоже очень плохо. 2. Мультиплексное статичное соединение - у него возникнет проблема: отправка огромного количества ненужных данных, ведь если пользователь выберет посмотреть всего лишь один спутник StarLink - он его посмотрит, но параллельно будут отправляться данные о всех 10.000+ спутников StarLink, пользователь всех их не увидит, а только один, но эти данные будут грузить сервис когда они вообще не нужны.

Здесь я рассказал только о минусах этих подходов, если хотите узнать подробнее в чем эти 2 подхода заключаются - смотрите прошлый пост(см. ссылку ниже).

Компромисс?

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

Как это будет работать?

На данный момент на сервисе сейчас 41 категория, каждая категория это одно соединение, что уже решает проблему с огромным количеством WebSocket'ов ведь их всегда будет не больше 41. Новые категории спутников появляются крайне редко из-за чего и сокеты будут очень медленно расти.

Пользователь будет заходить на сайт и выбирать спутник. Как только спутник выбран - считывается категория к которой принадлежит этот спутник и открывает для этой категории единый для всех WebSocket, который начинает каждую секунду слать на фронт список(List<SatelliteSPGDTO>) с данными выбранных спутников в этой категории. На данный момент список состоит из 1 элемента потому что выбран только один спутник.

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

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

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

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

Микро доработки

1. Можно было бы сделать так, что если выбран только один спутник в категории, то он шлет на фронт просто сам класс напрямую, а не список. 2. Можно было бы вместо списка readonly record классов отправлять список структур, что было бы гораздо легковеснее, но для начала я решил попробовать метод с обычными DTO классами.

Сылки:

Сервис: OrbitX Открытый исходный код: GitHub Ссылка на пост с последним обновлением: Пост Ссылка на 1 часть: Пост

Всем спасибо за внимание, буду рад вашим идеям и предложениям. Финальную схему прикладываю :)

Подготовка к обновлению OrbitX v1.3 день 2: Компромисс | Сетка — социальная сеть от hh.ru Подготовка к обновлению OrbitX v1.3 день 2: Компромисс | Сетка — социальная сеть от hh.ru