|
Вопрос по чату
|
|||
---|---|---|---|
#18+
Здравствуйте . Слегка застрял при написании чата. Есть табличка шапки и табличка списка сообщений . Когда приходит новое пишется в таблицу сообщений и у шапки меняется ссылка на последнее сообщение . Таким образом пытаюсь обеспечить проверку наличия новых сообщений . У пользователя есть поле последнего прочитанного. Вроде все ок. Но потенциально при добавлении сообщения можно нарваться на дедлок. Если вдруг придёт одновременно несколько сообщений для одного пользователя в рамках одного чата. Можно как то победить? Архитектурно . Можно все написать на редисе. Как оперативное хранилище. Но и тут в этом случае надо делать блокировку. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 10:07 |
|
Вопрос по чату
|
|||
---|---|---|---|
#18+
Swv Если вдруг придёт одновременно несколько сообщений для одного пользователя в рамках одного чата. Значит сделай так, чтобы этого не случилось. Например, однопоточная обработка приходящих сообщений тебя спасёт. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 14:16 |
|
Вопрос по чату
|
|||
---|---|---|---|
#18+
База реляционная? Если нет, возьмите реляционную Swv Когда приходит новое пишется в таблицу сообщений и у шапки меняется ссылка на последнее сообщение . Альтернатива 1. Последнее прочитанное сообщение (хранится на клиенте): Код: sql 1. 2.
Проверить наличие непрочитанных сообщений: Код: sql 1. 2. 3.
Альтернатива 2. Дополнительное поле "сообщение прочитано". Дефолтное значение - "не прочитано". Выборка всех непрочитанных: Код: sql 1. 2. 3.
После выгрузки на клиента - обновить значение поля для всех вычитанных сообщений. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 17:27 |
|
Вопрос по чату
|
|||
---|---|---|---|
#18+
Никанор Кузьмич База реляционная? Если нет, возьмите реляционную Swv Когда приходит новое пишется в таблицу сообщений и у шапки меняется ссылка на последнее сообщение . Альтернатива 1. Последнее прочитанное сообщение (хранится на клиенте): Код: sql 1. 2.
Проверить наличие непрочитанных сообщений: Код: sql 1. 2. 3.
Альтернатива 2. Дополнительное поле "сообщение прочитано". Дефолтное значение - "не прочитано". Выборка всех непрочитанных: Код: sql 1. 2. 3.
После выгрузки на клиента - обновить значение поля для всех вычитанных сообщений. Реляционная. хранить на клиенте последнее прочитанное как то сомнительно. LocalStorage? Вариант с already_seen это получается надо будет держать отдельную таблицу, где хранить признак already_seen для каждого сообщения каждого пользователя чата? скажется ж на производительности? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2020, 19:54 |
|
Вопрос по чату
|
|||
---|---|---|---|
#18+
Swv Здравствуйте . Слегка застрял при написании чата. Есть табличка шапки и табличка списка сообщений . Когда приходит новое пишется в таблицу сообщений и у шапки меняется ссылка на последнее сообщение . Таким образом пытаюсь обеспечить проверку наличия новых сообщений . У пользователя есть поле последнего прочитанного. Вроде все ок. Но потенциально при добавлении сообщения можно нарваться на дедлок. Если вдруг придёт одновременно несколько сообщений для одного пользователя в рамках одного чата. Можно как то победить? Архитектурно . Можно все написать на редисе. Как оперативное хранилище. Но и тут в этом случае надо делать блокировку. Архитектурно это очередь. Пока сообщение не взято из очереди, оно не прочитано. Организовать очередь можно кучей способов. Есть куча решений. Выбирай не хочу. :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
28.09.2020, 06:41 |
|
Вопрос по чату
|
|||
---|---|---|---|
#18+
Swv, Идешь по таблице с сообщениями, блокируешь строку, отправляешь пользователю, если успешно то добавляешь строку в таблицу отправленных и удаляешь из таблицы сообщений на отправку, если не успешно то снимаешь блокировку и в зависимости от причины, либо переходишь к следующей строке либо прекращаешь отправку. Асинхронное подтверждение приема клиентом сообщения будет сложнее и логику нужно реализовывать на обоих сторонах. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.10.2020, 19:42 |
|
Вопрос по чату
|
|||
---|---|---|---|
#18+
mad_nazgul Архитектурно это очередь. +1 graycode Идешь по таблице с сообщениями,.. ох уж эти орхетекторы :facepalm: ... |
|||
:
Нравится:
Не нравится:
|
|||
06.10.2020, 18:30 |
|
Вопрос по чату
|
|||
---|---|---|---|
#18+
У Oracle есть механизм select... for update skip locked. Правда я вообще не понимаю откуда в этой задаче могут быть блокировки и зачем они автору, если ему просто нужно раздать клиентам из таблички данные которых у них еще нет, то все гораздо проще, либо таймстемп, либо завести change number, соответственно клиент запрашивает все данные change number которых больше чем change number последнего сообщения полученного клиентом. Если проблема в попытках проапдейтить таблицу шапки, так не надо класть последний таймстемп/change number в нее. mad_nazgul Архитектурно это очередь. Пока сообщение не взято из очереди, оно не прочитано. Организовать очередь можно кучей способов. Есть куча решений. Выбирай не хочу. :-) Когда сообщение взято из очереди его больше там нет, внезапно кому то захочется перечитать все сообщения за последние сутки (данные на клиенте были потеряны), куда очередь прикладывать? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.10.2020, 19:51 |
|
Вопрос по чату
|
|||
---|---|---|---|
#18+
Swv Но потенциально при добавлении сообщения можно нарваться на дедлок. Если вдруг придёт одновременно несколько сообщений для одного пользователя в рамках одного чата. Создайте таблицу пользователь - чат - номер сообщения, строка таблицы является семафором, сообщения добавляются по следующему алгоритму: транзакция открывается, update строки с номером сообщения - инкремент номера, insert в таблицу сообщений нового сообщения с полученным на предыдущем шаге номером, транзакция закрывается. Транзакции через семафор, быстрые и короткие, никаких дедлоков быть не должно. На клиенте хранится номер последнего принятого сообщения, если он отличается от номера сообщения в таблице "пользователь - чат - номер сообщения" (читатели не должны блокировать писателей), значит есть новые сообщения. У пользователя может быть не одно устройство с клиентской частью чата, на разных устройствах может быть разное состояние, т.е. последнее полученное сообщение и соответственно его номер может отличаться. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2020, 01:17 |
|
Вопрос по чату
|
|||
---|---|---|---|
#18+
Swv Но потенциально при добавлении сообщения можно нарваться на дедлок. Это ещё надо постараться. Мне даже сходу не приходит в голову, как выстроить архитектуру так, чтобы это было возможно. Впрочем, есть универсальный ответ - используй serializable. Тогда дедлока заведомо не будет, максимум некоторые транзакции будут отваливаться по cannot serialize - но в этом случае их будет достаточно просто-напросто повторить. Для чата самое то. Swv Если вдруг придёт одновременно несколько сообщений для одного пользователя в рамках одного чата. Обычно в чате сообщения для всех пользователей, а адресат - в лучшем случае необязательное информационное поле. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2020, 04:18 |
|
|
start [/forum/topic.php?fid=33&msg=40002618&tid=1547088]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
202ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
50ms |
get tp. blocked users: |
1ms |
others: | 298ms |
total: | 597ms |
0 / 0 |