kuchumovn
@kuchumovn

Можно ли иметь зеркало базы данных в окне обозревателя, основываясь только на push'ах с «частичными обновлениями»?

Имеется сайт, который ставит своей задачей отображение списка сущностей так же, как они есть в базе.
То есть, как бы, зеркальное отражение того, что сейчас есть в базе.
«Инфа» должна быть «100%».
По времени может быть маленькая задержка, равная времени путешествия push-сообщения с обновлением от сервера в окошко обозревателя.
Можно ли, основываясь только на таких «частичных обновлениях», иметь точную копию базы в обозревателе?

База: MongoDB.
Реплики: пока не рассматриваем, т.к. там, наверное, всё гораздо сложнее, и не факт, что кто-то вообще знает как.

Если это имеет какое-то значение, то сервер: Node.js

Поясняю:
* Есть «коллекция» тем в базе
* У кажой темы есть рейтинг
* Андрей плюсует шестую сверху (по рейтингу) тему так, что она выходит на четвёртое место
* Иван в это же время минусует эту же самую тему так, что после плюсовки Андрея, она выходит на пятое место (предположим, что алгоритм рейтинга — это не просто сумма плюсов и минусов, а более сложная формула, в которой операции нельзя менять местами)
* Василий в это же время, по ajax'у, запрашивает пять самых «заплюсованных» тем из базы
* Пока updatе'ы Андрея и Ивана пишутся в базу, база может асинхронно (это же highload) отдавать «старые» данные, и выбирает Василию пять тем с самыми свежими ответами, исключая пока ту самую тему
* update Андрея завершился, и теперь select из базы будет видеть этот update
* сервер рассылает всем подключенным «клиентам» «частичное обновление» по websocket: «Заплюсована такая-то тема»
* update Ивана завершился, и теперь select из базы будет видеть и этот update тоже
* сервер рассылает всем подключенным «клиентам» «частичное обновление» по websocket: «Заминусована такая-то тема»
* и только в это время Василию, по ajax'у, в обозреватель (тормознуто) возвращаются данные с пятью самыми «заплюсованными» темами на то время, когда Андрей и Иван как бы ещё ничего не сделали

Задача кода в обозревателе Василия — делать всё что угодно, чтобы этот список пяти самых «заплюсованных» тем действительно являлся таковым.
Сейчас он противоречит базе данных, т.к. не содержит вообще тему, которую плюсовали и минусовали в примере.
«Частичные обновления» уже пропущены, и они не сделали того, для чего задумывались — в то время, когда они приходили, ещё даже данные о темах не пришли.

Вопрос: Как переработать код, чтобы только лишь «частичными обновлениями» иметь всегда точную копию базы данных?

Пока склоняюсь к полному обновлению данных, скажем, раз в 10 секунд, и push'ам в качестве ни к чему не обязывающего бонуса.

Ещё думал о неких «vector clocks» — это вести журнал с update'ами, и таблице присваивать некую версию.
Тогда, Василий, получив свою выборку, знал бы, что версия коллекции тем этой выборки = 123, а уже пришли update'ы с версиями 124 и 125 (которым, соответственно, пока сказали «подождать на диванчиках»).
Василий применил бы эти update'ы, и получил бы точную копию базы данных в обозревателе.

Но я не нашёл способа поставить таблице в соответствие такую «версию».
Хранить в отдельной таблице «версии_коллекций» не прокатит, т.к. работа (в MongoDB) с разными коллекциями не «транзакционна», что переводится как «за двумя зайцами погонишься — ни одного не поймаешь».
Скажем, мы обновляем коллекцию тем, потом делаем increment версии этой коллекции в коллекции версий, и получаем, как можно подумать на первый взгляд, версию выборки.
Но в промежутке между нашим обновлением темы и запросом версии из коллекции версий, кто-то уже может записать успеть другое обновление тем, и версия может получиться, в этом случае, больше той, которая соответствует данной выборке, и то «частичное обновление», которое должно было бы по идее потом наложиться на настоящую версию — не наложится, т.к. два раза их нельзя применять.

Может быть даже кто-то из местных знает, как организовать такую версионность в MongoDB.
Спрашивать у «них» пока не стал — мб есть уже какое-то решение.
Если здесь не ответите — пойду к «ним» на форум спрашивать.

** По идее, можно использовать SQL'ную базу данных, но мы здесь рассматриваем, вроде как, highload. Может быть кто-то посоветует не MongoDB, а что-то ещё, подходящее под требования этого вопроса.

*** Запостил вопрос «им». Мб чего ответят.

**** создал «им» запрос в jira'е
  • Вопрос задан
  • 2776 просмотров
Пригласить эксперта
Ответы на вопрос 1
7workers
@7workers
Вы можете попробовать вмешаться в пространственно-временной континиум и сделать так, чтобы весь мир подождал, пока запрос тормознутого Василия идёт от сервера к браузеру. Если без шуток — посмотрите на это с другой стороны — как разрешить Василию нажимать кнопку «обновить» ТОЛЬКО когда никто не делает изменения в базе? Как убедится что на у него на экране последние, свежие данные? mongoDB Вам, по-моему, не подходит если у Вас такие требования.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы