LINUX.ORG.RU

Помогите придумать алгоритм нотификации об изменениях в чатике/треде

 


1

4

В СУБД хранится тред/чатик. Физически хранится ПОЧТИ как массив языка Си (побитый на блоки, возможно, а блоки, возможно, лежат в других дата-центрах, но реализация не меняет сути). Логически как std::vector или как [] в js/python, скажем. Список не сортирован дополнительно никак, кроме порядка добавления в его конец. Там нет поля timestamp_nanosec и какого-то индекса по нему: кого раньше добавили в массив, тот и раньше. В объекте «сообщение» может быть конечно timestamp, но на него всем похрен и нужно оно только чтобы клиент видел какое-то время сообщения.

Из СУБД сообщения треда можно доставать по индексу (номеру от начала списка с нуля). Причём, индекс совершенно честный - как в тупом массиве на Си: если в треде было 1 млн сообщений, а потом модератор дропнул 100 с начала (0…99), то все индексы съехали на 100 вниз - называвшийся ранее 500 стал называться 400.

Данная СУБД отлично всех устраивает, особенно экономически, поддерживая сотни тысяч запросов/сек на самой дешёвой бомжатской виртуалке. Главное, чем она интересна, это как раз экономика и дубовая простота.

Опишем сценарий, когда это выходит боком.

Клиент залогинился в чатик, СУБД отдала ему 10 сообщений с конца. Причём, на каждом сообщении, при передаче на клиент, наклеен его индекс в массиве/списке - чтобы клиент знал в каком месте треда находится. Предположим, в треде было 1000 сообщений. На клиенте окажутся сообщения с индексами [989…999]. Клиент крутит чатик вверх, упирается в конец простыни и хочет подгрузить ещё штук 10 сверху. Шлёт серверу запрос R1: «дай [978…988]».

И тут наступает жепь-ебрилло:

Пока запрос R1 летел на сервер по сети, на сервере было дропнуто первых 2 сообщения и все индексы съехали. Клиент получит дубли пары сообщений (те, что у него уже были на сервере попадут в интервал R1 в результате съезда индексов). Это пережить можно - получил дубль - выкинул. Жепь-ебрилло похлеще: пока летел R1 на сервере дропнули сразу первых 100 сообщений. На клиент придёт ответ: «not found» вообще. Уже потом конечно до клиента долетит нотифайка про «drop 0…99» и клиент всё поймёт, но инфаркт в клиенте уже произошёл и всё умерло.

В общем, сгенерите какую-нибудь идею о борьбе с данным рассинхроном.

Если посмотреть на такую чатиковую систему как Slack, то там у каждой сообщеньки однозначный ID = «timestamp.timestamp_microsec» и дропание сообщений где-то в начале треда никак не затрагивает ID остальных сообщенек в этом треде. Я даже могу подумать, что у них в базе вообще все сообщеньки всех тредов лежат в одной таблице с этим адским primary_key (timestamp.timestamp_microsec) и это там ничему не противоречит, но я так не хочу чё-то пока.



Последнее исправление: igloev (всего исправлений: 1)
Ответ на: комментарий от Shadow

Я в BI так делал. Брат жив.

Так в ClickHouse любят инсертить, т.к. у него любая операция стоит секунду времени - 1 там строка или 1 млн строк.

igloev
() автор топика
Ответ на: комментарий от Shadow

В антифроде я тоже так делал. А в DWH данные вообще терабайтами данные лить собирались.

Но ты же в курсе, что это другое?

WitcherGeralt ★★
()
Ответ на: комментарий от igloev

Если записал - отправляю клиенту delivered(true) и все счастливы

Транзакционнность на стороне клиента? Такое себе.

Иначе бы всякие гуглы

Потому я выше и задавал вопрос про нагрузки.

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

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

WitcherGeralt ★★
()
Ответ на: комментарий от WitcherGeralt

Транзакционнность на стороне клиента? Такое себе.

На стороне сервера, точнее даже СУБД. Она авторитарно добавила в список и авторитарно выставила номер этому сообщению. Клиента только уведомляют. Понятия транзакций тут нет вообще нигда.

igloev
() автор топика
Ответ на: комментарий от WitcherGeralt

А, блин, я сначала умно сказал, потом подумал...

Shadow ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.