Имеется сайт, который ставит своей задачей отображение списка сущностей так же, как они есть в базе.
То есть, как бы, зеркальное отражение того, что сейчас есть в базе.
«Инфа» должна быть «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'е