Веб-разработчик
0,0
рейтинг
29 сентября 2013 в 10:57

Разработка → Tutorial Derby.js tutorial


Надеюсь вы уже прочитали пост про сравнение фреймворков и сделали правильный выбор. Теперь дело за малым — обуздать этого непокорного жеребца, освоить так сказать не паханную целину, ну в общем вы поняли. Предупреждаю, изучение Derby вызывает изменение парадигмы. Мир веб-разработки для вас больше никогда не будет прежним.




Вместо предисловия



Пост написан по мотивам вопросов в комментариях и сообщениях на Хабре.
Полагаю что вы уже знакомы с Derby и создали своё первое hello world. Если нет, то крайне рекомендую это сделать прямо сейчас. А вот несколько примеров приложений с комментариями. Ибо здесь мы будем говорить об общих, сложных для понимания моментах.
В примерах кода — Coffeescript. Надеюсь у людей знакомых только с js не будет проблем с этим.
Также в примерах я использую ид в виде 12341243. в реальности это будет guid.

Приложение Derby



Каждое приложение Derby — это расширенное приложение Express. То есть вы можете использовать connect.js, серверные routes и т.д., как вы это делаете в обычном Express приложении.
Одно Derby приложение состоит из одного серверного приложения (Express) и одного или нескольких клиентских. Например вы можете разделить сайт для пользователей и админку, и не загружать пользователям темплэйты и бизнес-логику от админки.

Первый запрос



При первом запросе от клиента на сервере обрабатывается нужный route и сгенерированный html отправляется на клиент вместе с клиентской частью Derby приложения (темплэйты, model, browserify с модулями, бизнес-логика). Клиент первым делом видит html, а всё остальное подгружается следом. В дальнейшем, при изменении url, routes будут отрабатываться на клиенте и генерировать html там же. Если js в браузере отключен, то routes отрабатываются только на сервере и html генерируется всегда на сервере, как обычный статический сайт.

Routes



Routes работают как на сервере, так и на клиенте с помощью tracks. Если на клиенте не находится нужный route, то запрос просто проваливается на сервер. То есть на сервере может быть больше routes, чем на клиенте, например, для загрузки файлов и т.п.

Html



Derby имеет встроенный шаблонизатор — немного измененный Handlebars. Есть модуль для Jade.

Связка с данными осуществляется так:
динамическая (данные изменяются при изменении html и наоборот)
<input type="text" value="{_page.name}" />, <h2>{users.12431243.age}</h2>

статическая (вывели и забыли)
<input type="text" value="{{_page.name}}" />, <h2>{{users.12431243.age}}</h2>


Темплэйты состоят из секций: Tille, Head, Body, Footer, Scripts и др. Вы можете, например, в layout-темплэйте задать Head и Scripts (если они одинаковые для всех страниц), а в других задавать только Title и Body.

Model



Model — это объект с api для работы с данными. Все манипуляции с данными происходят через него.
Model может существовать как на сервере, так и на клиенте. На сервере может быть несколько моделей, на клиенте — только одна.
Модели на сервере можно создавать для каждого запроса
model = req.getModel()

либо не зависимо от запросов из store
model = store.createModel()

на клиенте модель всегда тут:
model = require('derby').app.model


Если модель создается для первого запроса от клиента, то после всех манипуляций с ней, она сериализуется и отправляется на клиент. В противном случае на клиент отправляется пустая модель.

Path



Все данные представлены в виде path, который состоит из названия коллекции, ид и свойств данного объекта.
Например:
user = model.get 'users.12341234'
userName = model.get 'users.12341243.name'
model.set 'customers.12341234.properties.isIdiot', true
model.set 'customers.12341243.properties', {justMadeOrderForBillionDollars: true, isIdiot: false}


Fetch, Subscribe



При создании model — пустая.
emptyObject = model.get()

Есть два способа заполнить ее данными fetch и subscribe
fetch — просто достает данные из бд и помещает их в модель.
model.fetch 'product.12341243', 'users', -> console.log 'теперь у нас в модели продукт и все пользователи'

subscribe — динамически связывает данные из бд с данными в модели
model.subscribe 'products', -> console.log 'все продукты синхронизированы'

Теперь если мы поменяем данные в модели
model.add 'products', {name: 'Awesome brand new product'}

То эти изменения запишутся также и в бд. И если есть другие модели (на других клиентах или на сервере), подписанные (subscribe) на эти данные, то изменения также добавятся в эти модели.

Queries



Вам не обязательно подписываться на всю коллекцию. Можете подписаться на определенную выборку с помощью queries.
ids = model.get '_page.ids'
$customersWithSomeIdQuery = model.query 'customers', {'id' => { "$in" => ids}}
model.subscribe $customersWithSomeIdQuery, ->
  myCustomers = model.get $customersWithSomeIdQuery


Для каждой бд синтаксис queries будет свой. В данном случае Mongo Queries.

Store



Объект на сервере в единственном экземпляре, из которого создаются все модели и в котором происходит вся магия.
Store связан со всеми моделями. Для связи с моделями на клиентах используется browserchannel. Веб-сокеты не используются, потому что не гарантируют порядка доставки сообщений, что крайне важно для OT. browserchannel — это «socket.io от Google», также используется в Gmail.
Данные с клиентов мержатся в бд с помощью Share.js, это реализация Operational Transformation. Позволяет разрешать конфликты, учитывая версию данных. Клиенты могут уходить на долгое время в оффлайн, изменять данные в своих моделях, после этого их данные запишутся в бд с учетом изменений от других клиентов за это время. Это очень похоже на то как в своё время работал Google Waves (OT в share.js и Google Waves пишет один человек).

Live-db



Live-db — это хранилище данных для share.js. Состоит из двух частей:
1) Redis — обязательно. Share.js использует redis pub-sub для синхронизации клиентов, потому что в pub-sub в mongo вводит ряд ограничений (коллекции должны быть определенного размера), по этому redis со своей скоростью и отсутствием ограничений идеален для этого. Также в redis находится кэш последних операций (сами задаете сколько). Этот кэш как раз и позволяет мержить данные с клиентов ушедших в оффлайн на долго.
2) Сами данные могут храниться в любой базе данных. Но на данный момент есть адапетр только для Mongo DB. Написать адаптер довольно легко.
Историю всех операций можно не хранить, можно хранить в той же бд, что и данные, можно хранить в другой бд.

Архитектура



Снизу вверх:
live-db — это обвертка над redis и mongo чтобы сделать событийную бд.
share.js — это OT, используя live-db
racer — это работа с данными: store, model. На основе share.js
derby — это routes (tracks), templates, views.

Вы можете отдельно использовать live-db, share.js, racer, tracks и др части. Вы не можете использовать racer отдельно от share.js, либо share.js отдельно от live-db. Вы не можете использовать derby отдельно от racer, ибо derby привязано к модели данных racer.

Масштабирование



Вы можете запускать несколько Derby приложений (каждое со своим store), работающих с одной бд (live-db).

Какие еще есть сложности?

Материалы по Derby.js
Махаев Владимир @vmakhaev
карма
13,0
рейтинг 0,0
Веб-разработчик
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (83)

  • +2
    … потому что в mongo нету событий...

    blog.mongodb.org/post/29495793738/pub-sub-with-mongodb
    • +1
      Спасибо за ремарку. Поправил пост.

      Имелась ввиду не возможность для большинства приложений использовать pub-sub в Mongo DB из-за ограничений.
  • 0
    Одно Derby приложение состоит из одного серверного приложения (Express) и одного или нескольких клиентских.
    А где-нибудь есть пример одного серверного и нескольких клиентских?
    • +1
      Вот тут есть два приложения App и Login.
      А это они же в виде объектов на сервере.
      login = require('../login')
      main = require('../app')
      
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Derby.js работает только с Redis, за которым может быть любая БД. В официальной документации описан только Redis+MongoDB.
      • 0
        Есть возможность написать адаптер для mysql, если так хочется. Это будет не трудно.
        • 0
          А есть ли подобные в общем доступе? А то для LiveDB я не нашёл адаптеров под mysql :(
          • 0
            Нету. Напишите, выложите, будет в доступе.

            Вот как выглядит адаптер для mongo. Но мой взгляд не сложно.
            • 0
              Мне кажется, для mysql все может быть несколько сложнее, все-таки монго штука безсхемная.
              • 0
                Я к сожалению не силен в mysql, не скажу. Возможно.
                Мне интересно также в чем необходимость использовать именно mysql? Может и Mongo на худой конец сойдет? А? :-)
                • 0
                  Народ, наверное, join-ов хочет, да и анализировать ИМХО sql-ные базы лучше (aggregate и map/reduce монговские — не так удобны, по-моему).

                  Хотя мне самому mySql не очень нравится, тогда хотя бы уж postgres с полноценными транзакциями.
            • 0
              Есть ли адаптер для Redis? Зачем авторы используют 2 хранилища? Если Redis обязателен, то почему бы не использовать только его?
              • +1
                Потому-что Redis — это In-memory бд. Все данные лежат в оперативной памяти и их размер ограничен как вы понимате. Конечно вы можете купить много памяти, но это всегда ограниченно. Для каких-то проектов это возможно. Я согласен.
                Вторая проблема — это то что Redis с настройками по умолчанию сохраняет данные на диск периодически. То есть большую часть времени данные не синхронизированны и при неполадках потеряются. Можно поменять настройки (чтобы записывалось на диск после каждой операции), но тогда скорость работы Redis сильно упадет и по сути сведет на нет все его достоинства.

                Адаптера для Redis нету. Зато есть адаптер для mongo.
                Redis используется для Pub-sub и кэша операций. Данные хранятся в mongo.
                • 0
                  Ясно, спасибо.
                  В этом случае можно было бы, например, использовать JugglingDB или написать адаптер для этой ORM. Это позволит в т.ч. и «реляционщикам» угодить, да и вообще ;)
                  • +1
                    JugglingDB — это интересный проект. Спасибо за ссылку.
                    Но в derby он будет как третия рука. То есть добавит абстракции, а главное его достоинство — бд на клиенте не будет использовано.
                    Адаптеры для live-db тоже своеобразные (там же OT) и не факт что JugglingDB тут пригодится тоже.
                • 0
                  Можно поменять настройки (чтобы записывалось на диск после каждой операции), но тогда скорость работы Redis сильно упадет и по сути сведет на нет все его достоинства.


                  Это не так. Почитайте про fsync и вообще как устроена работа с диском в линуксах. Если не форсить врайт в дисковый кеш, то скорость будет «хорошей», а данные зафакапятся в случае фейла ОС, а не редиса.
                  • 0
                    Спасибо за уточнение.

                    Я конечно почитаю, но вы можете подробнее расписать? Как будет при RDB, как при AOF? Какая скорость, какая надежность? Я думаю многим будет интересно и полезно. Если есть какие-то тесты, вообще будет здорово. Тут даже пост можно написать.
                    • 0
                      Сразу же нагуглил этот топик — redis.io/topics/persistence
                      Но, да, поддерживаю, с теcтами было бы веселее, особенно в сравнении с mongo.
                    • 0
                      Простите, я не хочу этого делать, кроме того не считаю себя достаточно компетентным :)

                      Я просто уточнил, что вообще то писать транзакционный лог это нормально и потеря производительности здесь если и есть, то не столько критична, как у вас написано, зависит от типа синка. В общем все как и с другими БД.
    • +2
      Сам использую Derby для разных целей. Есть большой проект crm-erp системы. Есть мелкие сайты, где даже нету базы данных, а есть только статичные страницы, генерирующиеся на сервере. Везде это крайне удобно и в тему.

      Derby — очень гибкая штука. Если пойдете на слона, то можете из нее собрать пушку, А если на воробья — то рогатку.
      • 0
        Есть ли опыт «под нагрузкой»? Как себя ведет?
        Какие бы вы рекомендации дали?
        Что однозначно «стоит» делать, а что «не стоит»?
        • +1
          К сожалению опыта «под нагрузкой» как такового нету. Мой проект — интранет для одной компании.

          Создатели Derby сейчас пилят проект Lever. И где-то писали, что сейчас слабое место (в плане произодительности) не синхронизация данных, а шаблонизатор. По этому в данный момент шаблонизатор переписывается и выйдет в версии 0.6. Это будет не раньше, чем через пару месяцев.
      • 0
        CRM-ERP на монго, мне очень интересно на это посмотреть. Я с трудом, но могу представить CRM на NoSQL но вот ERP уже не могу. Не могли бы написать хотя бы поверхностную статью по архитектуре.
  • 0
    Спасибо за статью, по Derby.js ощущается острейшая нехватка обучающих материалов.

    Но к сожалению, это не туториал, а что-то вроде FAQ.
    • +1
      Спасибо за отзыв. Рад если помогло.

      Давайте идею для туториала тогда. Про что написать? Что не понятно? Примеры какие нужны?
      • +3
        Рад если помогло.

        Не помогло. Дело вот в чем.

        Я верстальщик, хорошо знаю HTML и CSS (SASS), с Linux — на вежливое «ты». Я достаточно освоил клиентский JS и немного Ruby, чтобы задуматься о том, чтобы слезть с пресловутого Drupal. Встал вопрос о выборе фреймворка для изучения.

        С моим текущим уровнем подготовки мне хватит способностей, чтобы освоить, например, AngularJS + Rails/Padrino. Но у DerbyJS порог вхождения настолько чудовищно высок, что я теряюсь, даже не начав. Node/Express для меня — темный лес. С серверным JS я не работал никогда. Redis в глаза не видел. Настройка окружения Bower и Grunt (и подцепление Ruby'шных SASS и Compass, без которых я не могу) представляется мне сложнее, чем написание самого приложения. И это я еще не говорю о смене парадигмы программирования.

        Звучит достаточно жалко, да. Но поймите, что среди читающих вашу статью людей, которые способны сходу взять этот материал на вооружение, — единицы, а таких растерянных как я — большинство.

        Поэтому имеет место огромная потребность в обучающих материалах, начиная с самых азов: настройка окружения Node/Grunt/Bower/Redis/MongoDB, азы Node, азы Express, первые шаги на Derby, азы Redis и MongoDB, азы Heroku (благо, как я недавно узнал, у них есть беслптный тариф)… Всё разжевывать и скармливать по ложечке. В противном случае получается как в том анекдоте. :(

        Так что на вас вся надежда. В рунете людей, хорошо знающих Derby, совсем немного, а готовых прикладывать усилия для его популяризации — единицы. Но самое смешное и печальное то, что даже на английском языке обучающих материалов по Derby — чудь более, чем нифига.
        • +1
          Но самое смешное и печальное то, что даже на английском языке обучающих материалов по Derby — чудь более, чем нифига.
          Блин, полностью с вами согласен. Даже туториала ни одного нормального, есть один жалкий, но он по сути позволяет разобраться лишь с тем, как дерби установить и создать (автогенерируемую) болванку для приложения без всяких пояснений работы… :(
          • +1
            Может мне на английском тогда написать туториал? :-)
            • +1
              Можно и на английском. Лишь бы туториал хоть какой-то был.
        • +2
          Спасибо за добрые слова. Особенно мне понравилась фраза про «вся надежда только на меня». :-)

          Вряд ли имеет смысл писать туториалы по Redis или Mongo DB. Думаю их и так достаточно.
          Тем более на первом этапе не нужно про них почти ничего знать.

          Node и Express можно тоже в принципе освоить походу. Хотя какую-нибудь книжку по Node прочитать не было бы лишним (ибо не похож на другие платформы).

          Grunt я не использую. Derby автоматом обновляет html, css на клиенте при изменении. А для coffeescipt`а (пишу на нем) я использую:
          coffee -w
          

          Что такое Bower я узнал только сейчас. Но так и не понимаю зачем он нужен если есть browserify и npm-пакеты на клиенте. Может вы мне объясните?

          Итого есть две идеи для туториалов:
          1) С нуля с настраиванием окружения и прочее до hello world.
          2) Написать какое-то приложение шаг по шагу. Что это может быть? интернет магазин? crm-система? социальная сеть? только давайте не супер сложное что-то.

          Что еще могу для вас сделать?
          • +1
            Фишка Bower — в вытягивании библиотек прямо с GitHub'а. Если вам нужна JS-приблуда, доступная на GitHub и отсутствующая в npm, вы можете написать конфиг для Bower, и он будет ее вытягивать для вас (и ваших коллег) автоматом, при этом добавлять исходник библиотеки в систему контроля версий не нужно. Я погуглил, есть средство для оборачивания Bower в Browserify.

            По Node, Express, Redis и MongoDB писать отдельные статьи, разумеется, не нужно. Но в статье по Derby требуется осветить все эти инструменты с полного нуля и в той мере, которая необходима для создания учебного приложения.

            По поводу двух ваших вариантов, мне кажется, что второй пункт является логичным продолжением первого. Вы натолкнули меня на мысль заглянуть на TodoMVC.com — учебное приложение, выполненное на всех фреймворках, и Derby там уже есть! Причем там в README даже неплохая подборка ссылок.

            Но вот пошагового туториала о настройке окружения и написании учебного приложения там нет. Берите готовенькое и разбирайтесь как сможете.

            Так что можно взять в качестве цели именно TodoMVC.

            Готов посильно участвовать в затее, но не знаю, чем я без знаний Derby и всего остального могу быть полезен.
            • +2
              Для npm в package.json вы можете тоже прописывать git-репозитарии. Ну а то что добавлять npm модули в систему контроля версий или нет, тут зависит от приложения. Например если вы деплоите из git, то наверно лучше там же и держать всю папку node_modules.

              Я смотрю Derby TodoMVC приложение как раз использует Bower. Но я всё равно не понимаю зачем он :-)

              Кстати по поводу настройки окружения: Derby — это по сути обычное Express приложение. Можно использовать туториалы для Express.

              Ну ок. С меня пара-тройка туториалов по Derby. С вас их изучение. Договорились?
              • +1
                Конечно. Буду первой жертвой. :D
              • 0
                Если можно, то в первом же материале затроньте тему с моделями и обновлением данных. Это, imo, самое интересное. Не хотите завести импровизированное русскоязычное коммьюнити? Я бы присоединился.
                • +1
                  Хорошо.

                  Что значит «завести импровизированное русскоязычное коммьюнити»? Хочу наверно. Но что это? :-)
                  • 0
                    Ну, например, гугл-группу, гугл+ группу или фейсбук группу для русскоязычных разработчиков под Derby. Хотя, наверное, это будет мертворожденная затея.
                    • 0
                      Есть англоязычная googlegroup. Там сидит народ со всего мира. Русские тоже есть. На самом деле я просто советую перечитать там все статьи хотя бы за последнее время чтобы понимать что происходит. Особенно интересны ответы от созадателей Nate, Brian, Joseph.
                      Вопросы тоже там задаются и все пытаются помочь кто чем может.
              • 0
                Я уже думал никто не возьмется и будет очередной «крутой» фрэймворк, до которого надо дорасти. Не надо никаких групп вконтактике/гугле/фэйсбуке. Достаточно активного обсуждения на SO как у метеора и ресурса с парой-тройкой туториалов. То есть так, чтобы хоть кто-то понял, а потом из тех кто понял кто-то еще и захотел поделиться знаниями. Потом как по PHP расплодится туториалов и всем станет хорошо, иначе будет метеор :)
                У меня сильное желание постичь серверный js, так как знакомство с клиентским прошло кмк вполне отлично, но начинать с ноды со-товарищи вместо удобного фрэймворка как-то не хочется.
                Так что жду с нетерпением туториалов.
                • 0
                  • 0
                    Он самый.
                • +1
                  Derby — это надстройка над express, а тот, в свою очередь, над connect, поэтому от «ноды со-товарищи» здесь не деться.
                • 0
                  Спасибо.
                  Буду чаще появляться на SO. Там можно как-нибудь подписаться на tag, чтобы уведомления приходили?
                  • 0
                    Можно
                    • 0
                      Как? :-)
                      • 0
                        Регистрируешься, переходишь по stackoverflow.com/tags, вбиваешь derbyjs, наводишь мышку на выбранный tag (derbyjs выделенный сереньким), ждешь пол секунды — всплывает небольшое окошко с описанием тега, в правом верхнем углу есть кнопочки «subscribe» и «rss», выбираешь нужную и, вуаля, готово.
                        • 0
                          Спасибо. Сейчас нашел. :-)
        • +2
          Про MongoDB, вы ещё успеваете на MongoDB for Developers, там как раз основы + Python.

          Ссылка.
          • 0
            Тогда уж лучше — education.mongodb.com/courses/10gen/M101JS/2013_October/about — сам его прошел (точнее сегодня последний день :) — хороший курс. На английском, но с субтитрами.
            • 0
              Ну, каждому своё) Я поэтому и дал ссылку на общую страницу, где можно выбрать нужный курс.
            • +1
              Спасибо за линк.
        • +1
          Азы Node, Express, Mongo — learn.javascript.ru/nodejs-screencast
        • 0
          Как вариант, хотя и скупой: github.com/codeparty/derby-examples
  • 0
    Вы не можете использовать derby отдельно от racer, ибо derby привязано к модели данных racer.
    В каком объеме в ToToMVC используется racer?
    • +1
      Все объекты model и store — это racer. Без них никак.

      Другое дело что здесь racer не подключен к бд (так тоже можно). И все изменения хранятся в MemoryStorage, то есть в памяти. Если вы перезагрузите приложение, всё сотрется.
      • 0
        Вроде как в ТЗ на ToDoMVC было прописано, чтобы все хранилось в localstorage браузера.
        • 0
          Значит в ТЗ ошиблись :-)
  • 0
    как у него дела с ограничением доступа к БД? к определённым полям, объектам?
    • 0
      к определённым полям
      Как я понял (на данный момент) объекты передаются целиком, отбора по полям нет.

      Из документации:
      Note that projections are not supported; only full documents may be returned.
      • 0
        а запись, удаление, изменение объекта?
        т.е. как сделать ограничение к БД?
    • +1
      Есть плагин для racer: racer-access
      Но в данный момент ограничивать доступ можно только к колекциям или сущностям.
      Ограничить доступ к полям нельзя. Это связано с тем, что это требует некоторого изменения работы share.js. Проблема известная. Находится в todo, так сказать.

      Использовать примерно так:
      racerAccess = require 'racer-access'
      derby.use racerAccess
      store.allow 'change', 'users', (some usefull arguments) -> return true or false
      
      • 0
        или сущностям
        — это в смысле отдельным объектам?
        • +1
          Да. Под сущностью (entity) я имею ввиду объект в бд с ид.
  • +1
    Хотелось бы побольше узнать про OT в derby, в контексте конкурентного изменения произвольных моделей.

    OT в объеме статьи в викепедии на примере конкурентного редактирования строки текста я понимаю; но обычно модель данных приложения куда сложнее, а различных мутирующих операций тоже намного больше. Весь этот уровень, где творится OT-магия — он прозрачен для разработчика?

    Год назад все было намного проще — режим «кто последним записал, тот и выграл», плюс отдельно OT-подобный режим, который не работал :)
    • +2
      FAQ по OT

      Если в двух словах: OT — это операционное преобразование. Каждая приходящая операция, перед тем как внести свою лепту в бд, преобразовывается, учитывая все предыдушие операции над текущими данными.

      В OT многое зависит от типа данных. Самый простой вариант — это строка. В racer, например — json. Здесь — все типы, которые поддерживает share.js. Как вы понимаете ничего не мешает добавить туда свой тип.

      Уровень довольно прозрачен, но требует определенных знаний.

      Ну а вообще конечно, как говорят, курите исходники. Есть только один человек, который точно знает как работает эта чертова штуковина.

      Вы абсолютно правильно сказали, что в Derby 0.3 была оптимистичная модель разрешения конфликтов и подобие OT. В Derby 0.5 добавили share.js, для чего потребовалось практически полностью переписать racer. Сейчас эта штука работает крайне хорошо и стабильно.
      • 0
        Ага спасибо, нашел у них описание поддерживаемых операций над json.
        Краткое резюме как я понял — все операции имеют первым аргументом путь. Если путь пролегает через массив(-ы), индексы будут скорректированы с учетом конкурентных операций удаления и вставок в эти массивы. Операции типа insert, delete, replace object имеют семантику «кто последний записал, тот и выиграл» — то есть путь до места модификации OT скорректирует как надо, а сам объект будет вставлен как есть, никакой магии.

        В OT многое зависит от типа данных.
        Мне кажется, начинать стоит с модели данных приложения, и операций над этой моделью определяемых приложением. Разумеется высокоуровневые application-specific операций оперируют конкретными типами данных. Но

        Can OT solve semantic consistency problems? Ответ — из фака — нет может.

        Я это понимаю так — если OT-магия применяется на уровне типов данных то сохранения консистентности в модели данных приложения («семантическая корректность») никто не обещает.

        Ну то есть можно наверно использовать share.js как OT движок и тщательно определять все application-specific операции и их трансформации. Но это какую голову надо иметь!

        Или использовать типы данных с поддержкой OT как есть, потенциально получая сломанные данные в результате работы OT («сементическая корректность»). Как такие вещи вобще тестировать?

        В общем картина получается безрадостная :(
        • 0
          Вот что называется «зри в корень» :-) Те вопросы и проблемы которые вы поднимаете очень важны.

          Я не считаю себя экспертом в OT и наверное лучше эти вопросы задать Joseph`у. Я думаю он с радостью на них ответит. Но как вы сами пишите share.js для типа json оперирует целыми объектами. Не это ли обеспечивает «семантическую корректность»?
        • 0
          Не нужно паники. Я разобрался.

          Как я и предположил в соседнем комментарии, share.js оперирует целыми сущностями (объектами в бд с ид). Для этого у каждой сущности есть версия, которая меняется при любых изменениях данной сущности. Таким образом обеспечивается «семантическая корректность». То есть данные не теряются ни при каких обстоятельствах.

          По поводу application-specific.
          Для того чтобы добавить share.js в racer, ее пришлось «слегка» переписать (0.6 — 0.7). Таким образом share.js уже является application-specific, в том плане, что это OT для веб-приложений.

          Ну а головы у создателей Derby — то что нужно:
          Nate раньше работал продакт-менеджером Google Search Images.
          Brian — создатель everyauth и mongoose
          Joseph писал OT для Google Waves.
          • 0
            Таким образом обеспечивается «семантическая корректность». То есть данные не теряются ни при каких обстоятельствах.
            Семантическая корректность это другое. В примере из FAQ речь идет про соответствие строки нормам английского языка. Обе правки сами по себе оставляют текст в грамматически—корректном состоянии, а объединение операций дает некорректную строку.
            edit1(ins,11,'s'): 'OT preserve operation intention' -> 'OT preserves operation intention'
            edit2(ins,2,'can '): 'OT preserve operation intention' -> 'OT can preserve operation intention'
            result: 'OT can preserves operation intention'
            

            Точно так же, как текст на естественном языке, объекты приложения должны удовлетворять определенным ограничениям. Каким именно — зависит от приложения.

            Хороший пример сходу придумать не могу (избыточность хранимых данных не в счет).
            • 0
              Да, видимо, я так и не разобрался. Вы определенно в чём-то правы.

              Задал ваш вопрос Joseph`у. Он ответил. Предлагаю переместить нашу дискуссию туда.
  • 0
    Клиенты могут уходить на долгое время в оффлайн, изменять данные в своих моделях, после этого их данные запишутся в бд с учетом изменений от других клиентов за это время.

    Оба клиента ушли в офлайн оба сделали какие-то изменения. Вернулись. Итоговый результат зависит от установленного вермени у клиента?
    • 0
      Привязка идет не ко времени, а к версии данных. Разрешние конфликтов осуществляется с помощью OT и зависит от операций.
      • +1
        При уходе в оффлайн у обоих актуальная версия 100500 оба делают одну правку. У обоих 100501. Правки сет на 1 поле, но значения разные. Кто победил?
        • 0
          Ничья :-)
          Если честно, то не знаю. Чуть выше в комментариях идет обсуждение OT и дальше там ссылка на ответы Joseph`а.
          Кто разберется и распишет в двух словах, тот получит водокачку!
          • 0
            Давайте уж лучше вы.
            • 0
              В этом случае у OT нету механизмов учесть обе правки. Будет оптимистичная модель. Одно из изменений потеряется.

              Для большинства приложений можно абстрагироваться от OT и думать об этом как о некотором черном ящике, который разрешает конфликты. В данной ситуации, например, OT из коробки смерижло бы без проблем операции с массивами, со строкой или инкремент числа. Но в некоторых случаях (как в вашем примере), при определенных условиях, данные могут теряться. Если это критично, то нужно опускаться на уровень OT и учитывать его работу. Также возможно содание application-specific типов данных.

              Эх. В чем только не разобрался за эти дни с вами. :-) Спасибо.
              • +1
                А какое потерятся не известно? Было бы не плохо, если первый кто реконнектнуля сделал бы правку, а второму прилетело бы исключение, что его версия данных не валидная.
                • 0
                  Тут Nate сказал, что исключения в случаях конфликтов возможно добавить в share.js. Тут я создал Issue для share.js.
  • 0
    Почему вебсокет не гарантирует порядок? Он же по TCP, а он гарантирует и доставку и порядок.
    • 0
      Joseph где-то писал, что он переигрался со всеми веб-сокетами, но не смог добиться от них того чего ему нужно для OT. Спросите его.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.