Как стать автором
Обновить

Комментарии 49

Очень интересный проект. Был на вашем докладе на MoscowJS в июле. Мы там с вами в лифте ехали :-)

Сам использую DerbyJS/ShareJS, а в CRDT всё никак не доходят руки покопаться. Если можно как-то сравнить на пальцах OT и CRDT, ShareJS и SwarmJS. Не помешала бы статья по CRDT для чайников.

Чего мне не хватает в ShareJS — так это кэша на клиенте. В принципе это можно добавить, но изначально не было заложенно и нужно немного менять и ShareJS, и RacerJS, и DerbyJS. Тут есть противоречие, потому что Derby в данный момент при первом запросе считывает данные из бд на сервере, рисует html, сериализует эти данные, отправляет на клиент вместе с html, там десериализует и восстанавливает такое же состояние, как было на сервере. Как мне представляется, если мы хотим кэшировать данные на клиенте и каждый раз их не тягать с сервера (а только разницу), то приложение должно сначала загрузиться, потом посмотреть в кэш, какие данные есть и уже потом отправить на сервер запрос, чтобы тот прислал разницу данных. Я полагаю, что у вас так и сделано.

Вот еще такой вопрос: есть ли поддержка подписки на запросы (и на отсортированные запросы)?
Спасибо!
Про кэш. В LWW-решениях появление кэша на клиенте достаточно просто, он там и есть обычно. В нашем (CRDT) тоже. В OT решении — крайне маловероятно. OT крайне уязвимо к асинхронности, там комбинаторный взрыв получается и всякие каки. А оффлайновая работа «с кэша» — это максимально асинхронный сценарий.
В Google Docs приковыряли кэш как-то, но там, насколько понимаю, использовано другое решение, чем при онлайновой работе, плюс какие-то экстеншены нужно устанавливать в браузер. Внутрь не смотрел, но стойкий химический запах ощущается.
Как я понял в таком случае разрешение конфликтов с помощью timestamp (CRDT) имеет преимущество над версией документа (OT). Ну а в LWW-решениях — кто последний вышел в онлайн, тот и затер всё что было до него. Правильно?

Вот еще вопрос. В ShareJS атомарность на уровне документа. То есть (по крайней мере для JSON-типа) можно подписаться на документ, коллекцию или запрос к коллекции (в том числе отсортированный). Нельзя подписаться на часть документа. Как это в SwarmJS?
1. В случае Causal trees конкурентные правки не перетираются. Там формально дерево символов, обход (depth first traversal) которого является текстом. Символы в дерево только добавляются. Timestamp используется для адресации и для упорядочения сиблингов (конкурентно вставленных в то же место символов). В Causal trees конфликтов, как таковых, нет.

2. Подписка идёт на объект, у него есть состояние, id и версия. Подписка на поле объекта возможна в API, но это фактически подписка на объект + фильтр.
Я правильно понимаю, что нету такого понятия как подписка на коллекцию или запрос к коллекции? Например, могу ли я подписаться на документы коллекции users, где user.age > 20, отсортированные по user.name, при этом skip = 20, limit = 10?
Коллекции есть, Set и Vector, и можно подписываться на события в объектах коллекции. Вручную отсортировать / профильтровать тоже можно.

Но обернуть запрос к БД в виде коллекции и слушать его — пока нельзя, но такой функционал в работе. Собственно, он неизбежно бекендо-зависимый, отдельная реализация для SQL, отдельная для Mongo, итд.
Да, в ShareJS это сделано в виде адаптеров к разным бд, например, Mongo.

Спасибо за ответы. Появилось некоторое понимание. Желаю вам и проекту успехов!
НЛО прилетело и опубликовало эту надпись здесь
Зависит от типа. Для простых объектов и ассоциативных массивов last write wins, где last определяется по timestamp. В Кассандре похожая схема (Лампортовская).
Для линейных структур (Vector, Text) используется merge по алгоритму Causal Trees. Результаты похожи на посимвольный 3-way merge (это чем патчи мержатся обычно в source control, только там всё построчно).
НЛО прилетело и опубликовало эту надпись здесь
Можете попробовать разобрать заметку про Causal Trees или посмотреть в блоге проекта пост про Лампортовы метки.
Что-то более подробное, с картинками, думаю, появится со временем тоже в блоге проекта.
Следите за @swarm_js.
НЛО прилетело и опубликовало эту надпись здесь
При добавлении 2х разных ключей в хеш один потеряется? Это не ок!
Библиотека Swarm — двуслойная.

Первый уровень — op-based CRDT основа, там реализованы «лог», «операция», «объект».

Второй уровень — собственно типы данных, написанные поверх основы.

Ничто не мешает добавить класс ManualMap, который будет сохранять и явно указывать на конфликты. Сейчас реализован только самый простой ширпотреб.
Очень напоминает sharejs с их 2-мя уровнями — ядро с OT, и типы данных поверх. И тоже ничто не мешать любой тип данных туда вворотить, например, для поддержки reach-text редакторов. Как у вас, кстати, с таким типом?
Совместный редактор нам писать приходилось. Учитывая, что таких web-based real-time collab editor codebases в мире 4-5, в смысле — которые использовались в продакшене, то мы, конечно, очень этим горды.

В Swarm такого типа пока нет, есть только plain text. Можем реализовать и RichText однажды. Если найдём заказчика, например, или как-то время выкроим. Там довольно много работы.
страница отрисовывается на сервере и приходит на клиента, как сжатый HTML
Расскажите о том, почему бы её и не отрисовывать на клиенте, тем разгружая сервер.
НЛО прилетело и опубликовало эту надпись здесь
Так долго.
* скачал html
* пропарсил
* запустил js
* вытянул данные
* отрисовал
* засунул в DOM
Браузеры хорошо оптимизированы по линии скачал-показал, плюс пробежки туда-сюда это RTT.
В DerbyJS тоже изоморфный шаблонизатор. Это хорошо по трём причинам:
1) SEO
2) Скорость загрузки приложения. Клиент сразу видит html, а не ждёт пока загрузится весь js и сгенерирует html.
3) Удобно использовать тот же шаблонизатор на сервере для рендеринга html для писем, документов и тп.
> Расскажите о том, почему бы её и не отрисовывать на клиенте, тем разгружая сервер.

Сразу вспомнилась книжка «Психбольница в руках пациентов» Алана Купера. В ней аргументируется, почему программистов нельзя допускать к принятию концептуальных решений, иначе они сделают всё, как удобно им самим, а не пользователям.
Грубовато. Разгруженный и быстрый продакшн сервер скорее нужен пользователям, а не разработчикам.
Выше уже ответили, что подход с рендерингом на сервере для пользователя оказывается быстрее. Можно потреблять контент, не дожидаясь, пока загрузятся скрипты и оживет интерактив.
А документация есть?
С этим пока слабовато. Есть примеры. Комментарии в коде swarm — скорее для разработчиков.
Обещаем скоро исправиться.
Жду нормальный вменяемый ликбез по CRDT — в магию не верю.
Заказываю следующую статью по CRDT :) Иначе абсолютно не понятны ограничения технологии.
Дайте две!
Я даю вам $100 и мы не открываем черный ящик.
Пока читал, подумалось, что очень перспективным направлением могла бы быть разработка виртуального серверного браузера.
Т.е. со стороны разработчика это выглядело бы как разработка для обобщенного клиентского браузера, но со всеми серверными фичами. А синхронизацией с «настоящим» (клиентским) браузером занимался бы сам виртуальный сервер.
Извиняюсь, промахнулся.

Правильно ли я понимаю, что вы предлагаете хранить у клиента всю историю изменений, как это делается в dvcs? У такого подхода есть несколько проблем:
1. большие требования ко клиенту по памяти (оперативной и/или дисковой)
2. необходимость шифрации данных (или хотябы их очистка при логауте)

Вариант с центральным хранилищем последней истины выглядит лучше. Клиент в этом случае может удалять старые версии по факту синхронизации.
Простите, что-то не до конца понял.
На фронтенде мы подключаем библиотеку, а что выступает в роли backend, куда идус запросы на синхронизацию, и где хранится информация?
Ага, так у вас на сервере тоже JS…
Ещё есть первый вариант java-версии (сервер и андроид). И на go ведётся разработка.
Я тут поразмышлял и пришёл к выводу, что Святой Грааль проблемы синхронизации находится в другой плоскости бытия — UX. В зависимости от самых разных факторов (не все из которых могут быть доступны в приложении) могут потребоваться различные стратегии слияния, так что любая автоматика неизбежно будет ошибаться. Поэтому разумнее положиться на то, что пользователь лучше знает как должны сливаться его изменения — достаточно в ленту его новостей постить информацию об автомерже его изменений с чужими (речь об «одновременных» изменениях одной сущности) и увидев её пользователь по необходимости правильно актуализирует значение. В этом свете сложная интеллектуальная система слияния версий становится лишней, уступая простым и предсказуемым (для пользователя) стратегиям.
Ну-ну, представьте это в Google Docs.
А в чём проблема с Google Docs?
Представьте UX при ручном мерже правок одного параграфа в Google Docs, я это имел в виду.
Я ничего не говорил про ручной мёрж.
А, ну тогда почти согласен.
Вы так абстрактно написали.
Вот 3-way merge — это сложно или просто?
По-моему, просто и предсказуемо.
В случае крупных конфликтов это очень сложно. Ну и интерфейсно он не очень органично вписывается. Хотя, 3-way merge для произвольных структур данных (не только текста) — это была бы крутая фича.
«увидев её пользователь по необходимости правильно актуализирует значение» — это, разве, не про ручной мёрж?
Это скорее ручное исправление последствий автоматического мёржа.
… и никто не спросил, что за девушка на фото. ладно, я спрошу — это кто такая ухоженная?
Не совсем въехал в этот CRDT, расширяющий сознание туториал жизненно необходим. Интересно, возможно ли натянуть модели из Swarm на иммутабельные структуры данных, загнать состояние в одну точку и затем шарить его части по компонентам? Эту технику привнес Om, она удобна и идет в массы. Ключевой фактор — состояние не размазывается по приложению.
Вопрос крайне интересный, и ответ на него сложный.
В Swarm, объекты имеют метку версии _version, которая позволяет установить факт наличия/отсутствия изменений, но иммутабельности нет.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий