Comments 49
Очень интересный проект. Был на вашем докладе на MoscowJS в июле. Мы там с вами в лифте ехали :-)
Сам использую DerbyJS/ShareJS, а в CRDT всё никак не доходят руки покопаться. Если можно как-то сравнить на пальцах OT и CRDT, ShareJS и SwarmJS. Не помешала бы статья по CRDT для чайников.
Чего мне не хватает в ShareJS — так это кэша на клиенте. В принципе это можно добавить, но изначально не было заложенно и нужно немного менять и ShareJS, и RacerJS, и DerbyJS. Тут есть противоречие, потому что Derby в данный момент при первом запросе считывает данные из бд на сервере, рисует html, сериализует эти данные, отправляет на клиент вместе с html, там десериализует и восстанавливает такое же состояние, как было на сервере. Как мне представляется, если мы хотим кэшировать данные на клиенте и каждый раз их не тягать с сервера (а только разницу), то приложение должно сначала загрузиться, потом посмотреть в кэш, какие данные есть и уже потом отправить на сервер запрос, чтобы тот прислал разницу данных. Я полагаю, что у вас так и сделано.
Вот еще такой вопрос: есть ли поддержка подписки на запросы (и на отсортированные запросы)?
Сам использую DerbyJS/ShareJS, а в CRDT всё никак не доходят руки покопаться. Если можно как-то сравнить на пальцах OT и CRDT, ShareJS и SwarmJS. Не помешала бы статья по CRDT для чайников.
Чего мне не хватает в ShareJS — так это кэша на клиенте. В принципе это можно добавить, но изначально не было заложенно и нужно немного менять и ShareJS, и RacerJS, и DerbyJS. Тут есть противоречие, потому что Derby в данный момент при первом запросе считывает данные из бд на сервере, рисует html, сериализует эти данные, отправляет на клиент вместе с html, там десериализует и восстанавливает такое же состояние, как было на сервере. Как мне представляется, если мы хотим кэшировать данные на клиенте и каждый раз их не тягать с сервера (а только разницу), то приложение должно сначала загрузиться, потом посмотреть в кэш, какие данные есть и уже потом отправить на сервер запрос, чтобы тот прислал разницу данных. Я полагаю, что у вас так и сделано.
Вот еще такой вопрос: есть ли поддержка подписки на запросы (и на отсортированные запросы)?
Спасибо!
Про кэш. В LWW-решениях появление кэша на клиенте достаточно просто, он там и есть обычно. В нашем (CRDT) тоже. В OT решении — крайне маловероятно. OT крайне уязвимо к асинхронности, там комбинаторный взрыв получается и всякие каки. А оффлайновая работа «с кэша» — это максимально асинхронный сценарий.
В Google Docs приковыряли кэш как-то, но там, насколько понимаю, использовано другое решение, чем при онлайновой работе, плюс какие-то экстеншены нужно устанавливать в браузер. Внутрь не смотрел, но стойкий химический запах ощущается.
Про кэш. В LWW-решениях появление кэша на клиенте достаточно просто, он там и есть обычно. В нашем (CRDT) тоже. В OT решении — крайне маловероятно. OT крайне уязвимо к асинхронности, там комбинаторный взрыв получается и всякие каки. А оффлайновая работа «с кэша» — это максимально асинхронный сценарий.
В Google Docs приковыряли кэш как-то, но там, насколько понимаю, использовано другое решение, чем при онлайновой работе, плюс какие-то экстеншены нужно устанавливать в браузер. Внутрь не смотрел, но стойкий химический запах ощущается.
Как я понял в таком случае разрешение конфликтов с помощью timestamp (CRDT) имеет преимущество над версией документа (OT). Ну а в LWW-решениях — кто последний вышел в онлайн, тот и затер всё что было до него. Правильно?
Вот еще вопрос. В ShareJS атомарность на уровне документа. То есть (по крайней мере для JSON-типа) можно подписаться на документ, коллекцию или запрос к коллекции (в том числе отсортированный). Нельзя подписаться на часть документа. Как это в SwarmJS?
Вот еще вопрос. В ShareJS атомарность на уровне документа. То есть (по крайней мере для JSON-типа) можно подписаться на документ, коллекцию или запрос к коллекции (в том числе отсортированный). Нельзя подписаться на часть документа. Как это в SwarmJS?
1. В случае Causal trees конкурентные правки не перетираются. Там формально дерево символов, обход (depth first traversal) которого является текстом. Символы в дерево только добавляются. Timestamp используется для адресации и для упорядочения сиблингов (конкурентно вставленных в то же место символов). В Causal trees конфликтов, как таковых, нет.
2. Подписка идёт на объект, у него есть состояние, id и версия. Подписка на поле объекта возможна в API, но это фактически подписка на объект + фильтр.
2. Подписка идёт на объект, у него есть состояние, id и версия. Подписка на поле объекта возможна в API, но это фактически подписка на объект + фильтр.
Я правильно понимаю, что нету такого понятия как подписка на коллекцию или запрос к коллекции? Например, могу ли я подписаться на документы коллекции users, где user.age > 20, отсортированные по user.name, при этом skip = 20, limit = 10?
Коллекции есть, Set и Vector, и можно подписываться на события в объектах коллекции. Вручную отсортировать / профильтровать тоже можно.
Но обернуть запрос к БД в виде коллекции и слушать его — пока нельзя, но такой функционал в работе. Собственно, он неизбежно бекендо-зависимый, отдельная реализация для SQL, отдельная для Mongo, итд.
Но обернуть запрос к БД в виде коллекции и слушать его — пока нельзя, но такой функционал в работе. Собственно, он неизбежно бекендо-зависимый, отдельная реализация для SQL, отдельная для Mongo, итд.
UFO just landed and posted this here
Зависит от типа. Для простых объектов и ассоциативных массивов last write wins, где last определяется по timestamp. В Кассандре похожая схема (Лампортовская).
Для линейных структур (Vector, Text) используется merge по алгоритму Causal Trees. Результаты похожи на посимвольный 3-way merge (это чем патчи мержатся обычно в source control, только там всё построчно).
Для линейных структур (Vector, Text) используется merge по алгоритму Causal Trees. Результаты похожи на посимвольный 3-way merge (это чем патчи мержатся обычно в source control, только там всё построчно).
UFO just landed and posted this here
Можете попробовать разобрать заметку про Causal Trees или посмотреть в блоге проекта пост про Лампортовы метки.
Что-то более подробное, с картинками, думаю, появится со временем тоже в блоге проекта.
Следите за @swarm_js.
Что-то более подробное, с картинками, думаю, появится со временем тоже в блоге проекта.
Следите за @swarm_js.
При добавлении 2х разных ключей в хеш один потеряется? Это не ок!
Библиотека Swarm — двуслойная.
Первый уровень — op-based CRDT основа, там реализованы «лог», «операция», «объект».
Второй уровень — собственно типы данных, написанные поверх основы.
Ничто не мешает добавить класс ManualMap, который будет сохранять и явно указывать на конфликты. Сейчас реализован только самый простой ширпотреб.
Первый уровень — op-based CRDT основа, там реализованы «лог», «операция», «объект».
Второй уровень — собственно типы данных, написанные поверх основы.
Ничто не мешает добавить класс ManualMap, который будет сохранять и явно указывать на конфликты. Сейчас реализован только самый простой ширпотреб.
Очень напоминает sharejs с их 2-мя уровнями — ядро с OT, и типы данных поверх. И тоже ничто не мешать любой тип данных туда вворотить, например, для поддержки reach-text редакторов. Как у вас, кстати, с таким типом?
Рекомендую статью Виктора: Operational transformation: the newest and coolest tech from the 80s
Совместный редактор нам писать приходилось. Учитывая, что таких web-based real-time collab editor codebases в мире 4-5, в смысле — которые использовались в продакшене, то мы, конечно, очень этим горды.
В Swarm такого типа пока нет, есть только plain text. Можем реализовать и RichText однажды. Если найдём заказчика, например, или как-то время выкроим. Там довольно много работы.
В Swarm такого типа пока нет, есть только plain text. Можем реализовать и RichText однажды. Если найдём заказчика, например, или как-то время выкроим. Там довольно много работы.
страница отрисовывается на сервере и приходит на клиента, как сжатый HTMLРасскажите о том, почему бы её и не отрисовывать на клиенте, тем разгружая сервер.
UFO just landed and posted this here
Так долго.
* скачал html
* пропарсил
* запустил js
* вытянул данные
* отрисовал
* засунул в DOM
Браузеры хорошо оптимизированы по линии скачал-показал, плюс пробежки туда-сюда это RTT.
* скачал html
* пропарсил
* запустил js
* вытянул данные
* отрисовал
* засунул в DOM
Браузеры хорошо оптимизированы по линии скачал-показал, плюс пробежки туда-сюда это RTT.
В DerbyJS тоже изоморфный шаблонизатор. Это хорошо по трём причинам:
1) SEO
2) Скорость загрузки приложения. Клиент сразу видит html, а не ждёт пока загрузится весь js и сгенерирует html.
3) Удобно использовать тот же шаблонизатор на сервере для рендеринга html для писем, документов и тп.
1) SEO
2) Скорость загрузки приложения. Клиент сразу видит html, а не ждёт пока загрузится весь js и сгенерирует html.
3) Удобно использовать тот же шаблонизатор на сервере для рендеринга html для писем, документов и тп.
> Расскажите о том, почему бы её и не отрисовывать на клиенте, тем разгружая сервер.
Сразу вспомнилась книжка «Психбольница в руках пациентов» Алана Купера. В ней аргументируется, почему программистов нельзя допускать к принятию концептуальных решений, иначе они сделают всё, как удобно им самим, а не пользователям.
Сразу вспомнилась книжка «Психбольница в руках пациентов» Алана Купера. В ней аргументируется, почему программистов нельзя допускать к принятию концептуальных решений, иначе они сделают всё, как удобно им самим, а не пользователям.
А документация есть?
Жду нормальный вменяемый ликбез по CRDT — в магию не верю.
Пока читал, подумалось, что очень перспективным направлением могла бы быть разработка виртуального серверного браузера.
Т.е. со стороны разработчика это выглядело бы как разработка для обобщенного клиентского браузера, но со всеми серверными фичами. А синхронизацией с «настоящим» (клиентским) браузером занимался бы сам виртуальный сервер.
Т.е. со стороны разработчика это выглядело бы как разработка для обобщенного клиентского браузера, но со всеми серверными фичами. А синхронизацией с «настоящим» (клиентским) браузером занимался бы сам виртуальный сервер.
Правильно ли я понимаю, что вы предлагаете хранить у клиента всю историю изменений, как это делается в dvcs? У такого подхода есть несколько проблем:
1. большие требования ко клиенту по памяти (оперативной и/или дисковой)
2. необходимость шифрации данных (или хотябы их очистка при логауте)
Вариант с центральным хранилищем последней истины выглядит лучше. Клиент в этом случае может удалять старые версии по факту синхронизации.
Простите, что-то не до конца понял.
На фронтенде мы подключаем библиотеку, а что выступает в роли backend, куда идус запросы на синхронизацию, и где хранится информация?
На фронтенде мы подключаем библиотеку, а что выступает в роли backend, куда идус запросы на синхронизацию, и где хранится информация?
На сервер github.com/gritzko/todomvc-swarm/blob/master/TodoAppServer.js
На сервере такой же код Swarm.
Ну, и локально оно кэширует всё в WebStorage. IndexedDB на подходе.
На сервере такой же код Swarm.
Ну, и локально оно кэширует всё в WebStorage. IndexedDB на подходе.
Я тут поразмышлял и пришёл к выводу, что Святой Грааль проблемы синхронизации находится в другой плоскости бытия — UX. В зависимости от самых разных факторов (не все из которых могут быть доступны в приложении) могут потребоваться различные стратегии слияния, так что любая автоматика неизбежно будет ошибаться. Поэтому разумнее положиться на то, что пользователь лучше знает как должны сливаться его изменения — достаточно в ленту его новостей постить информацию об автомерже его изменений с чужими (речь об «одновременных» изменениях одной сущности) и увидев её пользователь по необходимости правильно актуализирует значение. В этом свете сложная интеллектуальная система слияния версий становится лишней, уступая простым и предсказуемым (для пользователя) стратегиям.
Ну-ну, представьте это в Google Docs.
А в чём проблема с Google Docs?
Представьте UX при ручном мерже правок одного параграфа в Google Docs, я это имел в виду.
Я ничего не говорил про ручной мёрж.
А, ну тогда почти согласен.
Вы так абстрактно написали.
Вот 3-way merge — это сложно или просто?
По-моему, просто и предсказуемо.
Вы так абстрактно написали.
Вот 3-way merge — это сложно или просто?
По-моему, просто и предсказуемо.
«увидев её пользователь по необходимости правильно актуализирует значение» — это, разве, не про ручной мёрж?
… и никто не спросил, что за девушка на фото. ладно, я спрошу — это кто такая ухоженная?
Не совсем въехал в этот CRDT, расширяющий сознание туториал жизненно необходим. Интересно, возможно ли натянуть модели из Swarm на иммутабельные структуры данных, загнать состояние в одну точку и затем шарить его части по компонентам? Эту технику привнес Om, она удобна и идет в массы. Ключевой фактор — состояние не размазывается по приложению.
Sign up to leave a comment.
Holy Grail на стероидах: тотальная синхронизация и изоморфный JavaScript на Swarm.js