Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Разработка информационных систем [игнор отключен] [закрыт для гостей] / Вопрос по чату / 11 сообщений из 11, страница 1 из 1
25.09.2020, 10:07
    #40002430
Swv
Swv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по чату
Здравствуйте .
Слегка застрял при написании чата.
Есть табличка шапки и табличка списка сообщений . Когда приходит новое пишется в таблицу сообщений и у шапки меняется ссылка на последнее сообщение .
Таким образом пытаюсь обеспечить проверку наличия новых сообщений . У пользователя есть поле последнего прочитанного. Вроде все ок.
Но потенциально при добавлении сообщения можно нарваться на дедлок. Если вдруг придёт одновременно несколько сообщений для одного пользователя в рамках одного чата.
Можно как то победить? Архитектурно .
Можно все написать на редисе. Как оперативное хранилище. Но и тут в этом случае надо делать блокировку.
...
Рейтинг: 0 / 0
25.09.2020, 14:16
    #40002540
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по чату
Swv
Если вдруг придёт одновременно несколько сообщений для одного пользователя в рамках одного чата.

Значит сделай так, чтобы этого не случилось. Например, однопоточная обработка приходящих сообщений тебя спасёт.
...
Рейтинг: 0 / 0
25.09.2020, 17:27
    #40002618
Никанор Кузьмич
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по чату
База реляционная?
Если нет, возьмите реляционную

Swv
Когда приходит новое пишется в таблицу сообщений и у шапки меняется ссылка на последнее сообщение .
Не надо ссылок из шапки.

Альтернатива 1.
Последнее прочитанное сообщение (хранится на клиенте):
Код: sql
1.
2.
select max(message_id)
  from message_table


Проверить наличие непрочитанных сообщений:
Код: sql
1.
2.
3.
select count(*)
  from message_table
 where message_id > saved_max_id


Альтернатива 2.
Дополнительное поле "сообщение прочитано". Дефолтное значение - "не прочитано". Выборка всех непрочитанных:
Код: sql
1.
2.
3.
select *
  from message_table
 where already_seen = 0


После выгрузки на клиента - обновить значение поля для всех вычитанных сообщений.
...
Рейтинг: 0 / 0
27.09.2020, 19:54
    #40003126
Swv
Swv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по чату
Никанор Кузьмич
База реляционная?
Если нет, возьмите реляционную

Swv
Когда приходит новое пишется в таблицу сообщений и у шапки меняется ссылка на последнее сообщение .
Не надо ссылок из шапки.

Альтернатива 1.
Последнее прочитанное сообщение (хранится на клиенте):
Код: sql
1.
2.
select max(message_id)
  from message_table


Проверить наличие непрочитанных сообщений:
Код: sql
1.
2.
3.
select count(*)
  from message_table
 where message_id > saved_max_id


Альтернатива 2.
Дополнительное поле "сообщение прочитано". Дефолтное значение - "не прочитано". Выборка всех непрочитанных:
Код: sql
1.
2.
3.
select *
  from message_table
 where already_seen = 0


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


Реляционная.


хранить на клиенте последнее прочитанное как то сомнительно. LocalStorage?

Вариант с already_seen это получается надо будет держать отдельную таблицу, где хранить признак already_seen для каждого сообщения каждого пользователя чата? скажется ж на производительности?
...
Рейтинг: 0 / 0
28.09.2020, 06:41
    #40003180
mad_nazgul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по чату
Swv
Здравствуйте .
Слегка застрял при написании чата.
Есть табличка шапки и табличка списка сообщений . Когда приходит новое пишется в таблицу сообщений и у шапки меняется ссылка на последнее сообщение .
Таким образом пытаюсь обеспечить проверку наличия новых сообщений . У пользователя есть поле последнего прочитанного. Вроде все ок.
Но потенциально при добавлении сообщения можно нарваться на дедлок. Если вдруг придёт одновременно несколько сообщений для одного пользователя в рамках одного чата.
Можно как то победить? Архитектурно .
Можно все написать на редисе. Как оперативное хранилище. Но и тут в этом случае надо делать блокировку.


Архитектурно это очередь.
Пока сообщение не взято из очереди, оно не прочитано.
Организовать очередь можно кучей способов.
Есть куча решений. Выбирай не хочу. :-)
...
Рейтинг: 0 / 0
05.10.2020, 19:42
    #40005543
graycode
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по чату
Swv,

Идешь по таблице с сообщениями, блокируешь строку, отправляешь пользователю, если успешно то добавляешь строку в таблицу отправленных и удаляешь из таблицы сообщений на отправку, если не успешно то снимаешь блокировку и в зависимости от причины, либо переходишь к следующей строке либо прекращаешь отправку. Асинхронное подтверждение приема клиентом сообщения будет сложнее и логику нужно реализовывать на обоих сторонах.
...
Рейтинг: 0 / 0
06.10.2020, 18:30
    #40005923
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по чату
mad_nazgul
Архитектурно это очередь.


+1


graycode
Идешь по таблице с сообщениями,..


ох уж эти орхетекторы :facepalm:
...
Рейтинг: 0 / 0
06.10.2020, 19:51
    #40005946
graycode
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по чату
У Oracle есть механизм select... for update skip locked.

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


mad_nazgul
Архитектурно это очередь.
Пока сообщение не взято из очереди, оно не прочитано.
Организовать очередь можно кучей способов.
Есть куча решений. Выбирай не хочу. :-)

Когда сообщение взято из очереди его больше там нет, внезапно кому то захочется перечитать все сообщения за последние сутки (данные на клиенте были потеряны), куда очередь прикладывать?
...
Рейтинг: 0 / 0
07.10.2020, 00:06
    #40005986
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по чату
:double facepalm:
...
Рейтинг: 0 / 0
07.10.2020, 01:17
    #40005991
graycode
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по чату
Swv
Но потенциально при добавлении сообщения можно нарваться на дедлок. Если вдруг придёт одновременно несколько сообщений для одного пользователя в рамках одного чата.

Создайте таблицу пользователь - чат - номер сообщения, строка таблицы является семафором, сообщения добавляются по следующему алгоритму: транзакция открывается, update строки с номером сообщения - инкремент номера, insert в таблицу сообщений нового сообщения с полученным на предыдущем шаге номером, транзакция закрывается. Транзакции через семафор, быстрые и короткие, никаких дедлоков быть не должно. На клиенте хранится номер последнего принятого сообщения, если он отличается от номера сообщения в таблице "пользователь - чат - номер сообщения" (читатели не должны блокировать писателей), значит есть новые сообщения. У пользователя может быть не одно устройство с клиентской частью чата, на разных устройствах может быть разное состояние, т.е. последнее полученное сообщение и соответственно его номер может отличаться.
...
Рейтинг: 0 / 0
07.10.2020, 04:18
    #40005996
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по чату
Swv
Но потенциально при добавлении сообщения можно нарваться на дедлок.

Это ещё надо постараться. Мне даже сходу не приходит в голову, как выстроить архитектуру так, чтобы это было возможно. Впрочем, есть универсальный ответ - используй serializable. Тогда дедлока заведомо не будет, максимум некоторые транзакции будут отваливаться по cannot serialize - но в этом случае их будет достаточно просто-напросто повторить. Для чата самое то.

Swv
Если вдруг придёт одновременно несколько сообщений для одного пользователя в рамках одного чата.

Обычно в чате сообщения для всех пользователей, а адресат - в лучшем случае необязательное информационное поле.
...
Рейтинг: 0 / 0
Форумы / Разработка информационных систем [игнор отключен] [закрыт для гостей] / Вопрос по чату / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]