ermouth: (Default)

Написал админку для CouchDB – Photon.

То-есть уже есть две – Futon (исторически первый) и Fauxton (для новых версий). Второй – модный, но совсем неудобный, плюс в угоду моде очень сильно страдает информационная плотность. Первый – существует только для версий до 1.6.1 (актуальная – 2.1), тоже не слишком удобный, но всё прекрасно с информационной плотностью. Плюс у обоих проблемы с обновлением – то-есть поставил CouchDB и живи потом всегда со встроенной админкой в той версии, которая была на момент установки.

Я решил сделать и удобный, и с нормальной информационной плотностью, и обновляемый независимо от самой БД. Дополнительным ограничением было отсутствие любых опен-сорцных библиотек, происходящих из крупных корпораций. Последние события показали что их опен-сорц с гнильцой (привет, Фейсбук и Реакт).

Первые эскизы нарисовались в конце августа, примерно так:

Photon-1

В результате три эскиза превратились в полное приложение за две с небольшим недели:

Снимок-экрана-2017-09-10-в-17.32

Установка – просто курлом или копипастой засунуть в базу 1 (один) json-документ объёмом 1.5 мега. Обновление потом по одному клику из интерфейса, с AWS S3 CDN, так сейчас очень много кто делает.

Конечно же, приложение никогда не существовало в виде исходных файлов на файловой системе, вся разработка – в браузере, в CloudWall. Выглядит это примерно так:

Снимок экрана 2017-09-10 в 18.00.10

На картинке Photon запущен в окошке в среде разработки и просматривает сам себя: функция слева – исходник в IDE, функция открытая в окошке – она же, но в коде уже собранного Photon-а. Рефлект рефлекта, редкий зверёк.

Оч здорово получилось в целом, кто юзает CouchDB – рекомендую.

Couchbox

Jul. 27th, 2017 03:52 am
ermouth: (Default)

Месяц назад мы запустили публичную бету vezdelegko.ru, сервиса бронирования экскурсий, отелей и транспорта. Сервисы бронирования – сами по себе штука сложная, это как магазин, по которому надо вести учёт ассортимента на каждый день, причём ассортимент день ото дня меняется и цены зависят от дня и количества. Причём в магазине куча отделов, и партнёры сами управляют своим ассортиментом.

Дополнительно, в нашем случае сервис делался с прицелом на очень существенную масштабируемость как по ёмкости, так и по географии. Это автоматом предполагает архитектуру из многих узлов и распределённое хранение/обработку данных с последующей их репликацией и агрегацией. Под такую схему я придумал специальную архитектуру узла, которая потребовала платформы исполнения, это и есть Couchbox.

Снимок экрана 2017-07-27 в 2.26.24

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

Code follows data

Нативная CouchDB хранит в базах не только данные, но и код для predefined map/reduce запросов, по которым строятся высокоэффективные persistent индексы. Этот код, на JS или Erlang, хранится в документах рядом с данными и может распространятся между узлами в тех же потоках репликации, что и сами данные.

Couchbox, наша платформа, расширяет это всё механикой хуков, реагирующих на изменения документов в базе, и эндпоинтов – REST–концов, обрабатывающих входящие запросы через https. То-есть в те же специальные документы, где в обычной CouchDB живёт код функций индексов, для Couchbox-а можно добавить ещё и код функций хуков и внешних REST API эндпоинтов. Получается распределённая платформа приложений.

Особо примечателен факт, что с точки зрения установленного софта узлы не различаются вообще.

Весь специфический код, определяющий функциональную роль узла, приходит через БД. То-есть по мере обновления документов с кодом все обработчики по-горячему аккуратно заменяются на новые версии. Обработчики устроены примерно как амазоновские лямбды, функции без сохранения состояния, поэтому горячая замена вполне возможна.

Файлы – это очень скучно

Важный момент, как именно код функций попадает в БД.

Код лямбд вообще не существует в виде исходных файлов. Он создаётся в специализированной среде разработки, основанной на CloudWall и Ddoc Lab. Выглядит это примерно так:

Снимок экрана 2017-07-27 в 3.52.11

То-есть, сорцы, из которых собираются лямбды, хранятся в PouchDB в браузерах разработчиков, реплицируются в CouchDB на какой-то из узлов, собираются, а затем распространяются по остальным узлам.

Деплой обновлений и скорость разработки

Такая архитектура расслаивается на три части по критерию обслуживания:

  1. Убунта, CouchDB, Redis, node.js и nginx – фундамент со временем между рестартами в месяцы. Для обновления или рестарта фундамента нужен доступ к каждому узлу через терминал.
  2. Couchbox – платформа приложений с временем между обновлениями сейчас в недели, скоро станет в месяцы. Разрабатывается на файловой системе в обычных IDE, для обновления на узлах нужен доступ через терминал.
  3. Код приложений, очень гибкий, может обновляться и дополняться с высокой частотой. Для разработки и отладки как клиентской (UI), так и серверной части (REST API) приложений не нужно ничего, кроме браузера. Код деплоится по узлам автоматом.

Общий объём кода, написанного в браузере для этой системы, перевалил за 100К SLOC и пока всё просто прекрасно. Стартскрин бэкэнда выглядит сейчас вот так:

Снимок-экрана-2017-07-27-в-4.29

Я, в общем, доволен – это самая сложная штуковина, которую я когда-либо придумывал, и её получилось не просто сделать как задумано, но ещё и в плановые сроки почти уложиться. Как с самой платформой, так и с приложениями на ней.

И да, Couchbox is MIT licensed. Опенсорц наше всё.

ermouth: (Default)

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

Couchapp – это когда есть CouchDB, и она для всего, а больше кроме CouchDB ничего и нет. Я в чистом виде так ещё не делал, всегда был node.js ещё как минимум. В этот раз node.js нет, но в архитектуру couchapp добавлено два слоя – JS rewrite на сервере и PouchDB на клиенте.

JS rewrite, только появившийся в CouchDB 2.0 моими и @kxepal трудами, позволяет делать сложный раутинг прямо внутри БД. То-есть кастомные API, access control и тп.

Вторая фича, PouchDB на клиентах бэкэнда, – позволяет делать тяжёлые веб-приложения бэкэнда с отзывчивостью десктопного уровня, ну и работать при плохих соединениях. “Тяжёлые” – это значит ворочать бинарными данными в мегабайты, картинки там обрабатывать, пдф-ки, сложные виджеты инлайнить с данными в реальном времени.

Архитектура одного узла выглядит так (может быть из одной, двух или трёх физ. машин):

Read more... )
ermouth: (Default)

Внезапно вчера в Архангельске прошла мегаконференция StartupStandup и, хоть меня туда и не приглашали (какой из меня стартапер, ога), один сделанный нами проект там внезапно оказался.

Паче чаяния, проект по итогам голосования был признан лучшим и даже заказчику приз какой-то дали от Ростелекома.

Коль скоро заказчик проекта его официально презентовал, правда, больше с бизнесовой стороны, не вижу причин не расказать о solovki.pro с колокольни разработчика. Несмотря на то, что всё только-только из-под Under construction выведено, за некоторые вещи “уже не стыдно” (с).

Фронтэнд

С точки зрения посетителя – это калькулятор туров на Соловки. Кулькулятор сразу туры продаёт, а не только считает. Заказ или уже можно оформить, или вот-вот можно будет, ждём от Сбера подтверждение включения платежного шлюза.

Туры кастомизированы – то-есть выбирается транспорт, проживание и развлечения на месте. Калькулятор устроен таким образом, что знает capacity каждого ресурса на каждую дату и даёт заказывать соразмерно возможностям принимающей стороны.

Снимок-экрана-2016-03-17-в-19.03

В самом деле это агрегатор, то-есть фактически услуги оказывают разные компании. Агрегатор аккумулирует данные о номенклатуре услуг и их загруженности и отображает это всё пользователю в виде калькулятора.

Capacity, к слову, считается на сервере одним единственным хитрым map/reduce-ом всего на 200- SLOC.

Калькулятор – jQuery.my приложение, 120 с небольшим кб в исходных текстах. Сделан в CloudWall, там же и отлажен. На картинке вот калькулятор исполняется в отладчике, в окошке.

Снимок экрана 2016-03-17 в 19.31.50

Приложение сложное, потому что надо учитывать кучу сценариев и пограничных случаев – и у меня нет уверенности, что мы учли их все, хотя старались.

Самый простой пример – доступность номерного фонда отеля не на конкретную дату, а в диапазоне (надо брать наименьшие значения по набору, с нюансами). Посложнее: что делать при сдвижке дат – можно лучше сделать, чем сейчас, и тп.

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

Мобильную версию калькулятора пока не делали – заказчик посчитал, что подождёт.

Приложения бэкэнда

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

Веб-приложения бэкэнда с самого начала заточены под работу в сетях с ненадёжной и медленной связью, то-есть они offline-ready. Однажды загруженная вкладка с приложением прекрасно работает и без соединения и заказчивает/скачивает изменения в данных, когда оно появляется. С учётом качества связи в местах экологического туризма это не прихоть.

Когда соединение есть хотя бы плохонькое, в основном приложении данные обновляются моментально, есчо.

В самом деле приложения даже не знают, с каким набором данных они работают – всю синхронизацию за них делает платформа. Приложение просто делает this.db.get(), this.db.query() или this.db.put().

Например, вот так выглядит диспетчер со старыми тестовыми данными:

Снимок-экрана-2016-03-17-в-19.17

Окошки таскабельны, компоновка сделана под большие мониторы – чтобы можно было свободное поле вокруг календаря обвесить окошками. На мониторах поменьше и планшетах, правда, тоже нормально, просто не 7 дней помещается по ширине.

Из диспетчера можно отправлять СМСки и звонить – это важно, потому что климат на Соловках переменчивый и иногда надо туристов оперативно уведомлять.

Естессно, все приложения – манифесты jQuery.my.

Технологии

Особо детально не буду расписывать, потому что есть чувствительные данные в системе.

Серверная часть – node.js, патченная CouchDB и nginx. То-есть, основная часть кода на JS и немножко на Erlang-е. База крутится на SSD. Памяти на инстанс надо немного совсем. В общем, ничего необычного.

На админском бэкэнде смонтирован локальный CloudWall, который содержит все исходники и почти все средства разработки. CloudWall также обеспечивает эмуляцию рантайма клиентского бэкэнда – все пользовательские приложения запускаются с нативными данными прямо в IDE.

Вживую приложения бэкэнда исполняются прямо на клиентах и в большинстве случаев, когда дело не касается чувствительной информации, оперируют локальным – внутри браузера – working set’ом, который непрерывно синхронизируется с основным хранилищем.

Локальные данные позволяют трюки, которые затруднительны при обычной архитектуре – например, массивные map/reduce запросы. Вообще, серверные мощности бэкэнда очень скромны, потому что основной объём всякой тяжести вынесен в клиентские браузеры.

“Цена” поддержания канала постоянной синхронизации неожиданно невелика – примерно 14Кб в час, если новых данных не поступает/отправляется. Канал, кстати, гарантирует доставку в конечном итоге, сообщения не могут быть потеряны.

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

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

Поглядим, как это всё полетит )

UPD. Хехе, тут вот уже багов накидали. Аккурат на пограничные случаи. Поправили, но чует моё сердце, что это не последние.

ermouth: (Default)

Отрелизил сабж, релиз больше про рефакторинг/оптимизацию. Проковырялся неделю вечерами с профайлером, открыл много нового про GC и скорость регэкспов. Вот примерчик особенно злодейский:

Снимок экрана 2015-12-12 в 4.39.41

Попутно напишу вот про виджет с заглавной, оч хорошо на нём видно и что такое $.my, и что я там оптимизировал. Пример, собсно, по клику на картинку.

Снимок экрана 2015-12-12 в 4.28.49

В примере 100 строк кода, 2Кб, это с HTML-ем уже. Эти 2 Кб грузят внешние данные и делают из них master/detail.

Особая фишка – в левой колонке позиции таскабельны. И номера обновляются по мере перетаскивания, причём если справа открыта карточка и тыкнуто в поле ввода, то фокус не теряется.

Ну и если справа начать имя править, слева оно немедленно рефлектится. Причём можно даже начать тащить айтем слева и одновременно печатать справа )

Кто делал что-нибудь похожее хоть раз в жизни, знает, что 100 строк кода на такое – это вообще наглухо магия.

Инициализация этого виджета с 280 строками данных (каждая из которых – тоже форма) занимает примерно 300мс. По 1мс на форму. Флеймчарты до и после оптимизаций:

Снимок экрана 2015-12-12 в 5.57.37

Снимок экрана 2015-12-12 в 5.57.20

В самом деле 1мс – это чрезвычайно дохрена. Мы на каждую строку слева инциализируем по сути маленькое приложение, и это дорого. Увы, такой подход можно наоптимизировать ещё примерно только раза в 2 и будет потолок.

Но у меня есть план Б.

В jQuery.my 2.0 будет другой (точнее, ещё один) алгоритм. Во-первых, просто сам старт одинаковых форм станет быстрее, потому что полуфабрикат формы будет кэшироваться. А во-вторых, рендерить я их буду чанками.

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

Завтра-послезавтра days off.

Inliner

Sep. 10th, 2015 04:13 am
ermouth: (Default)

Почти довёл до нестыдного состояния офлайновый редактор контента зверски навороченный. Та-же технология, что и Ddoc Lab примерно, но это не стэндэлон, а больше компонент для других систем.

Тык по картинке – живое редактируемое демо. Стартует первый раз очень долго, может полминуты пыхтеть – загрузка не оптимизирована потому что ещё. Дальше всё летает пулей.

Снимок экрана 2015-09-10 в 3.56.50

Длина самого приложения, без обвеса – 100 Кб, а под углифаем-гзипом и вовсе 25-30 кило.

Я этот редактор как компонент уже впилил в Ddoc Lab, пока не задеплоил ещё. Собираюсь сделать под него шаблончик, который позволит на cloudant.com развернуть простенький блогодвижок в два копипэйста, реально.

Не без глюков всё пока, но на мой вкус редактор жирненький получился ) Медиум об коленку, ога.

ermouth: (Default)

У меня тут в процессе образовался нереальной красоты одностраничный документик со схемой архитектуры FEED CMS. Сделано спецом под ч/б принтер. Всегда пёрся от таких описаний, мне несколько раз попадались на выставках всяких, как правило в буржуйском исполнении. Станки там разные, расходники, инструментарий.  Очень коротко и сухо, с картинкой в стилистике инженерной графики. Whitepaper с инженерным уклоном, да.

architecture

Ну и на ddoc.me заработали платежи, для буржуев only. Потому что оказывается, через paypal один российский резидент не может платить другому российскому резиденту не в рублях. А у меня там USD, не знают в Лондоне про рубли блин.

Теперь вот “жду удачу, удача близится, нависает удача гроздьями”.

Ddoc Lab

Jul. 30th, 2015 11:31 pm
ermouth: (ang)

Зарелизил CloudWall 1.8, в который вошло новое приложение – Ddoc Lab.

Для этого приложения, выведенного стэндэлоном, сделал отдельный сайтик. Сейчас инглиш вычитывается и пытаюсь пофиксить merchant-account на пэйпэле (дичайший гимор). А так всё уже работает в хорошем приближении.

Клик по картинке – на сайт.

Снимок экрана 2015-07-30 в 23.10.38

Софтинка – довольно специализированное IDE, так что уважаемым читателям бложека вряд ли будут интересны подробности. А вот технологии под ним поинтересней.

Софтинка эта написана в полном CloudWall-е, а на сайте работает под его порезанной стэндэлон-версией. То-есть теперь у меня есть такая специальная версия CloudWall, которая поддерживает всего одно приложение и одну открытую БД на вкладку. И есть генератор этой мини-версии из большого CloudWall-а, да.

То-есть это позволяет релизить сингл пэкиджом из одного JSON-файла сразу и приложение, и ОС под ним. Этот JSON можно копипастить как документ в CouchDB – и приложение сразу взлетает на той базе, куда скопипащено.

Ещё заодно пробую “Pay what you want” модель монетизации – Ddoc Lab в виде JSON-а в некоторых случаях может быть просто бесценен ) То-есть это можно приложение поставить себе в CouchDB  в один копипэйст буквально – и заиметь человечий редактор индекс-функций и приложений у себя локально.

Такие дела.

ermouth: (ang)

Текущий набор иконок “публичных” приложений CloudWall выглядит так:

Снимок экрана 2015-07-08 в 10.28.48

Две последних – новое приложение, которое появится в CloudWall 1.8 и будет выложено стэндэлон-сервисом.

Приложение называется DDoc Lab и служит для разработки, линковки и публикации Couchapp-приложений произвольной структуры. То-есть, это специализированная IDE.

В самом деле редактировать и собирать можно не только Couchapps, но и любые сложные документы для CouchDB. Например, следующая версия FEED CMS пересобирается именно в DDoc Lab, и ускорение против работы в обычном IDE не просто кратное, а скорее на порядок. FEED естессно не Couchapp – просто код хранит в CouchDB, не более того.

Все прелести в пакете – инклюд внешних сорцов, сборка, валидация, частичное обновление, проверка целостности и прочая и прочая.

Началось всё вот с этого поста в рассылке CouchDB в мае. Выделить время в мае у меня не получилось, а в июне у меня куча времени выпало из-за боёв с кривизной PouchDB. Ну, в июле – не поздно )

Постановка задачи

В силу того, что CouchDB-документы – это не файл, а JSON плюс набор файловых аттачей, сборка приложений с файловой системы делается либо руками, либо специализированным CLI-тулом (раз, два). Что так, что так – дикий геморрой в самом деле.

Вообще, крива сама идея CLI-тулов, которым нужен или Питон, или node.js, чтобы собирать приложения для БД, которая себя позиционирует как единое решение для веба. В браузере это должно делаться.

Теперь вот делается.

Ну и под занавес скриншотик вот:

Снимок экрана 2015-07-08 в 11.03.41

Скоро на экранах! )

ermouth: (ang)

Написал за ночь сегодня логгер для следующеего релиза CloudWall, сейчас потестил – оч шустро вышло. Написал заметочку в корпоративной Стене и решил сюда кросспостнуть.

Под катом инженерные соображения про логгер для браузерной системы.

Клик чтобы раскрыть... )

Пока копировал псто, подумал ещё, что надо сделать фичу распознавания повторяющихся событий. И, может, это выпилить отдельной стэндэлон-библиотекой и на гитхаб сложить.

Справочно: скорость записи в localStorage небольших фрагментов (десятки килобайт) колоссальна: на моём i7 – сотни мегабайт в секунду в любом браузере. Это многократно превосходит среднюю скорость сериализации в JSON, например.

Коллеги, что я забыл про важные фичи лога?

ermouth: (Default)

У Гугла есть отличный сервис – PageSpeed Insights. Сегодня посравнивали dvinanews.ru – новостной ресурс местного правительства – с флагманами типа rbc.ru, lenta.ru, meduza.io и с несколькими менее значимыми.

Моя прекрасная FEED CMS уделывает по десктопной версии их всех )

Снимок экрана 2015-06-25 в 22.12.26

По мобильной версии – всех, кроме Медузы. У Медузы – 100 из 100 по удобству и чуть больше, чем у Двинаньюса, по коду.

Снимок экрана 2015-06-25 в 22.12.42

Сравнение с новостными сайтами правительств других субъектов РФ можно даже не приводить – их Двинаньюс опережает с бооольшим отрывом. Включая регионы с дикими бюджетами, типа Татарстана. И даже kremlin.ru – правда, всего на один балл.

От гордости просто разрывает ) Редчайший так то случай, когда правительственный ресурс опережает коммерческие проекты по качеству инженерного исполнения. Про архитектуру, админку и всякое такое я писал вот тут ermouth.livejournal.com/604509.html

Скоро кста откроем новостной ресурс ещё для одного субъекта, красивенький.

И да, если у уважаемых читателей из других регионов РФ есть на примете СМИ или пресс-центры с хорошей посещаемостью, в которых работают нормальные ребята, а инженерное/дизайнерское исполнение убогое – дайте им ссылочку на этот пост.

Месяца за три можно любой пресс-центр превратить в конфетку – причём мы не только в инженерном плане сделаем по-хорошему, но и редакцию круто подтянем по уровню.

И это не зарубежной выделки платформа, FEED сделан в России )

UPD. КДПВ вот придумалась )

feedvsother

FEED CMS

May. 20th, 2015 09:42 pm
ermouth: (Default)

Оформили в первом приближении нашу новостную CMS в продукт. Вот уж не думал, не гадал. Клик по картинке – на сайт в первой итерации.

Снимок экрана 2015-05-20 в 21.16.31

Сайт сделан как вспомогательный инструмент для прямых продаж, вся аргументация – не на технарей есчо. Не хватает примеров внедрений – они будут обязательно. Подбираем такие скриншоты, чтобы хотелось лизнуть, ну и ждём ещё отзывов от клиентов.

Основной рынок – обновление имеющихся ньюсфидов и пресс-центров. То-есть где есть огромные массивы материалов, но всё грустно с редакционной политикой, с раскладками, с качеством разметки, систематизацией и внешним видом.

FEED специально заточен под такие задачи – организацию высоконагруженного непрерывного потока информации лентами. Под статические сайты он не подходит – будет очень ограничивать и дорого стОит для статики.

Самое старое боевое внедрение FEED за два года отдало 5+Тб страничек и ни разу не упало, чихнуло разве что пару раз. Есть ещё одно внедрение, на котором в течение полугода менялись один за другим студенты и кому ни попадя права админов раздавались. Там такое с системой вытворялось, что даже я был удивлён, как её можно выкрутить – и тоже не разу не упала, но крепко, правда, спотыкалась.

Всё целиком, от первой до последней строчки, javascript. Весь бэкэнд и мобильная версия – jQuery.my-приложения. Исторический эскизик вот, с которого всё началось:

image

Всё немного посложней в жизни вышло, но примерно принцип понятен, как оно работает.

С Днём Рождения, FEED )

ermouth: (Default)

C целью “потрогать” arrow-функции в ES6 написал вот парсер выражений в польской нотации, простенький. Работает в консоли FireFox или в io.js, больше нигде не работает.

var polish = (function () {
  var ops = "+-/*".split("").reduce((a,b)=>(a[b]=Function("x","return x[0]=x.shift()"+b+"x[0],x"),a),{});
  return (s)=>s.split(/\s+/).reduce((a,b)=>(ops[b]?ops[b](a):!isNaN(b)&&b!=''?(a.unshift(+b),a):a),[]);
})();

polish ("10 1 2 3 + + *") напишет [60].

Пожалуй, я уже хочу стрелки в js. До этого как-то они мне не родными для js казались – ну и зря.

Atomic CSS

Apr. 20th, 2015 10:00 pm
ermouth: (Default)

21 января 2013 я написал про технику мнемонических CSS-правил, которую использую достаточно давно и нахожу исключительно удобной.

Оказывается, эту же технику использует Yahoo под названием Atomic CSS. Там прекрасный флейм в комментах кста.

Техника эта – когда мы пишем кучу правил типа .mt10 {margin-top:10px} или .fl {float:left} – особенно удобна, если сделать набор генерализованных правил большим, с частой сеточкой.

В CloudWall и системах, на нём построенных (общий объём выдачи с таких систем – 600К страниц в месяц есличо) объём таких правил в CSS-файлах – примерно 30Кбайт. Это 10Кб гзипом, меньше маленькой картиночки.

Игра свеч определённо стоит. Когда заранее неизвестно, что будет на странице и как могут конфликтовать селекторы, строить стайлшиты на основе БЭМ или подобных техник очень утомительно и получаются они жирнее.

В самом деле наилучший вариант – обе техники сочетать.

Большинство элементов в конструируемой странице (приложении, шаблоне) заранее определены по расположению и геометрии, встречаются однократно и, по-хорошему, отдельного CSS-правила для себя не требуют.

То-есть, даже очень сложные приложения требуют относительно скромных кастомных CSS-стайлшитов в стиле БЭМ – если подставить под БЭМ более “низкоуровневую” технику типа Atomic CSS.

В реальности это даёт вкусные каврижки. Скажем, для довольно сложного мобильного приложения весь CSS-код укладывается в 80 строк:

Снимок экрана 2015-04-20 в 21.45.51

Типичный объём CSS для таких приложений – полтысячи строк и больше, и конечно при БЭМ подходе чистоганом хрен их встроишь куда-то. А тут оно что на мобиле, что во всплывайке, что виджетом на странице одинаково работает и выглядит.

ermouth: (Default)

Выложил на гитхаб библиотечку ermouth/calc, которая за последние 10 лет сэкономила мне кучу денег и времени.

Библиотечка восстанавливает билинейную форму по нескольким значениям. В народном хозяйстве применение самое прямое.

Иногда известна дискретная матрица цен, прайс-лист, и нужно быстро посчитать промежуточные значения. Например вот по печати журналов (скриншотик с гитхаба):

Снимок экрана 2015-04-18 в 14.14.10

Фишка в том, что в большинстве отраслей народного хозяйства ценообразование – линейная комбинация нескольких параметров. А коль скоро она линейная комбинация, её можно более-менее точно восстановить, зная всего несколько значений.

Библиотечка позволяет скармливать ей прайсы с несколькими колонками и строками – тогда интерполятор будет… эммм… кусочно-билинейной формой, или как это правильно назвать?

Я с помощь этой библиотеки оперативно подбирал подрядчиков. У меня были наборы опорных точек для разных типографий и выбор между ними делал робот.

Нафига это нужно?

Обычно запрос цен в типографию занимает несколько часов – это если повезёт, а иногда и больше суток. А бюджет прикинуть надо вот прямо сейчас как правило.

Аналогично с доставкой. Аналогично с оптимизацией соотношения риск/маржа. Да сплошь и рядом в самом деле.

С этой библиотечкой достаточно запросить один небольшой расчёт (или посчитать самому опорные точки) – и вся картина ценообразования ясна, больше можно не спрашивать.

Снимок экрана 2015-04-18 в 13.26.17Применимость в UI

Интерполировать можно и по одной оси. Пример такого отображения – ползунок от 1 до 1000 шириной в 100 пикселей.

Хорошо бы, чтобы первые 10 пикселей цифры шли через 1, потом через 2, потом через 5, 10 и 25. То-есть чтобы дискретность повышалась при увеличении числа.

Это получается например так http://s3-eu-west-1.amazonaws.com/cdn.cloudwall.me/demos/calc-slider.html

Ну и онлайн-калькуляторы конечно. Все, что мы сделали, используют эту библиотечку.

Клиент даёт опорные точку, которые считает их экономист, они вставляются в калькулятор табличкой – а сайт делает всё остальное. Промежуточные значения интерполируются.

Ну и тизер в конце. Вообще, билинейная форма – это (0,2)-тензор. Но про тензоры в народном хозяйстве я в другой раз расскажу, да.

ermouth: (Default)

Перепозиционировал это всё как noBackend OS, с известной долей иронии каэш. Теперь и на гитхабе – https://github.com/ermouth/cloudwall

Снимок-экрана-2015-04-08-в-1.37.50 

Главные фичи

Оно теперь опенсорц. Установить можно на любой статический хостинг прямо из .tgz, там только html + js + json + css.

Исправлено куча багов, апгрейд библиотек сделан, примерчики добавлены, приложения обновлены. Ещё я там на заглавной выложил унылый шестиминутный скринкаст как за час сделать, отладить и задеплоить приложение для организации распределённых дискуссий. Целых 4кБ длиной приложение, ога.

И – тадам – это всё можно форкать и править/пересобирать форк самого CloudWall прямо в браузере. То-есть можно скачать себе в браузер исходники, это примерно так выглядит:

Снимок экрана 2015-04-08 в 1.38.45

Они все редактируемые, тоже прямо в браузере. Это не то-же самое, что на гитхабе, там уже собранная версия. Совсем исходники на гитхаб не выложить, потому что они файлами не существуют, только доками в базе.

Important notice

Если кто-то юзал или смотрел cloudwall.me до этого, не забудьте обновить системные приложения. Как войдёте – серая кнопка Check updates в левой панели внизу.

И да, информация о документе и всякие copy/delete теперь – через клик по иконке документа.

Сделано в CloudWall

CloudWall в текущей версии полностью написан и собран в CloudWall, только иконки не в окошке браузера нарисованы. Сам сайт cloudwall.me тоже управляется прямо из CloudWall.

Вообще, у меня лично внутрибраузерная боевая БД перевалила за 400 мегов. Полёт прекрасный.

---

Хвалите, поздравляйте, ставьте, пробуйте. На планшетах кста норм работает, да.

ermouth: (ang)

Год назад я запустил первую версию cloudwall.me. Жэжэшечка у меня тогда была закрыта, так что написал я об этом только в мае и в Medium.

clouds-09

В тот момент cloudwall.me работал на PouchDB 1.4 (это такая локальная NoSQL БД в браузере). Тогда она была дико глючная и медленная. За год PouchDB стараниями комьюнити доросла до 3.3 и стала вполне стабильной. Среда исполнения приложений на jquerymy за год тоже здорово подросла и в плане скорости, и в плане надёжности.

Плюс добавился IDE, плюс ещё всякие редакторы и приложения, плюс я сайт jquerymy переделал.

Короче, сейчас cloudwall.me – простейшая браузерная ОС, которая для работы не требует инет-соединения. Год назад я говорил (и думал), что ОС эта совсем игрушечная – но, похоже, что не такая уж и игрушечная.

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

И контракт этот – на разработку софта на платформе cloudwall.me. Offlline-ready, все дела. Интересно, что контракт сам меня нашёл.

Что дальше

CloudWall система уникальная в том плане, что её исходники не существуют в виде файлов.

Текущая версия CloudWall (платформы) создана внутри него самого, исходники – это JSON-документы в локальной браузерной БД. Синхронизированной, конечно, с удалёнными репликами CouchDB.

Сам сайт cloudwall.me – статически слинкованный – это один документ CouchDB с 32 аттачами. То-есть, чтобы запустить CloudWall у себя, как свой сайт, достаточно поставить CouchDB и скопировать в неё один-единственный документ. Больше ничего делать не надо – оно сразу заработает само.

В общем, я планирую довести это всё до стадии open-source для начала. Это не так и просто – потому что файлов нет, а на гитхаб можно положить только файлы, то-есть нужен трюк.

А дальше у меня есть соображения, откуда могут проявиться интересные деньги. Потому что если к этому прикрутить CoverCouch и сделать централизованные профили пользователей, получается распределённая ОС с безопасностью, пригодной для корпоративного сектора.

Что-то типа MS Active directory + DFS получается, только в браузере и для запуска js-приложений. Ну и без дикого сопутствующего гимора как в Винде. И клиенты по определению однопользовательские.

Но сначала я раскрою cloudwall. Скоро на гитхабе, да.

ermouth: (ang)
Задачка с эмуляцией JS-энджина CouchDB внутри моей волшебной библиотечки решилась в одно соображение. Там суть задачи – воссоздание для JS-функции довольно необычного scope, такого же, как внутри CouchDB. Сложность в том, что часть этого scope – это «системные» функции CouchDB, а часть – итераторы, зависящие от параметров конкретного запроса и результата работы map-функции.

«В лоб» задача решается просто – в каждом запросе к reduce делаем кусок исходника со всеми этими функциями и превращаем это все в исполняемый код рефлектором. Это очень просто, но совсем плохо по скорости и памяти, да и вообще довольно стрёмно. Первый же подход к снаряду показал, что это тупик – это примерно полгода назад было, и я задачку отложил.

А потом я как-то вспомнил про curried constructor в Scala. Сам по себе аналог в js никак специально не называется, но мне подумалось, что если этот концепт немного дополнить, то выходит как раз нужный мне функционал.

В результате получилось, что на каждую reduce-функцию у меня есть наполовину инстанцированный конструктор, в некотором смысле sсope-полуфабрикат. При каждом запросе reduce клиентом я этот полуфабрикат инжектирую итераторы, зависимые от параметров запроса, и исполняю. Такие конструкции V8 прекрасно оптимизирует – сама reduce-функция получается инстанцированной однократно, вызывается часто и оптимизируется в этой связи компилятором по-полной.

Выложил вчера на гитхаб, а сегодня ночью тесты гонял. Летает )
ermouth: (ang)

Нарисовался внезапно изумительной красоты кусочек кода, прокси-сервер на ноде (типа там для обхода CORS-блокировок например):

var app = require('express')(), request = require('request');
app.use("/proxy",function(req,res){req.pipe(request(req.query.url)).pipe(res)});
app.listen(80);

Обожаю за такие штуки javascript.

Появился этот код в процессе работы над прокси-сервером для CouchDB, который обеспечит per-document read ACL. Ну и попутно кучу других всяких рестрикшинов, которых в CouchDB сейчас нет, а очень бы хотелось.

Это всё небесплатно в плане производительности, но у меня получилось на бумажке построить схему, как это сделать всеобъемлющим, без щелей, и даже для reduce, а не только для map или выборки по ключам.

Первый подход к снаряду делался ещё летом под моим недостаточно чутким руководством, но я сам там ни строчки не написал, да и вообще мало внимания уделял. В результате получилось хоть и работающее, но далеко не всеобъмлющее и очень громоздкое решение.

“Не всеобъемлющее” означает, что API CouchDB где-то немного изменена, а где-то обрезана. А “громоздкое” – потому что много сложно связанного кода, и требует дополнительно Redis (это memcache) для кэширования и синхронизации ACL и сессий между потоками.

Это оказался подход тупиковый и меня недавно осенило, как можно обойтись без межпотоковых взаимодействий через временную БД. Картиночка цепей обработки раутером КучДБ-шного API в части GET-запросов в результате выглядит примерно так:

Снимок экрана 2015-01-22 в 19.42.31

То-есть это полное накрытие REST API, при этом получается не так и много разновидностей обработчиков (это которые зелёные и через запятую). Каждый обработчик строк по 30-50, может. Короткие довольно.

Попутно эта штука будет ограничивать к-во запросов, gzip-ить ответы и вести лог. Во всём остальном прикидываясь CouchDB.

Такой подход (per-document read ACL), если брать в общем, разрушает возможность построения колец из реплик, то-есть допустима только звезда. Скажем, есть три базы – главная и две у юзеров. Реплики у юзеров будут различаться – и если они реплицируются друг в друга минуя главную базу, то оба увидят документы друг друга.

Те не менее, жизнь показывает, что колец репликации надо избегать совершенно по другим причинам и в реальных сценариях их возникновение маловероятно. Например, две реплики “главной” БД, помещённые в два разных браузера, напрямую друг с другом соединиться уже не смогут.

Интересно, что общий подход к этой задаче я в обдумывал года два, пока не придумалось. В общем, скоро “смотрите на гитхабе” )

ermouth: (Default)

За каникулы случился minor version upgrade – добавилось немножко вкусных фич. Заодно оказалось, что это 10-й юбилейный релиз, да.

В jQuery.my теперь есть внутрисистемный pub/sub и управляемое наследование.

Radio/ listen

Pub/sub организован по принципу радио – каналы и подписчики. Подписчики – контролы в приложениях, они могут апдейтиться на сообщение в канале.

В отличие от типичных чисто js-реализаций pub/sub, я заюзал DOM. Просто мне надо иногда ограничивать вещание, примерно вот так:

unnamed

То-есть какие-то каналы броадкастятся всем, а какие-то приложение может ограничивать и наружу не выпускать. А какие-то и вовсе просто глушить.

С учётом того, что $.my это loosely coupled система, такую функциональность – что по границам каждого приложения может проходить radio-relay c ретранслятором/обработчиком/глушилкой – оказалось не так просто сделать по канонам.

Любое $.my приложение может позаимствовать у соседа, например, какую-то всплывайку, чуток её декорировать и использовать как свою. Или даже не декорировать. И этот позаимствованный манифест должен вести себя, как родной, в том числе и в плане цензуры радио.

В общем, скомбинированные события jQuery и обычный pub/sub вполне решают проблему без создания каналов с частными именами. Также не нужен контроль за тем, жив ли ещё подписчик или его уже прибило по пути и это последние коллбэки в темноте дёргаются – то-есть можно не отписываться от канала в деструкторе, тебя автоматом отпишут по выбытию.

Expose / inherit

Пример с заимствованием кода у соседних приложений во время рантайма имеет ещё одну сторону – принимаемый сниппет по идее должен получать какие-то методы или данные от принимающей стороны.

Скажем, разные приложения, подключенные более-менее унифицированным интерфейсом к разным БД, могут хотеть заимствовать всплывайку, выводящую данные о документе.

Было бы удобно ей сразу передавать кукую-то ветку манифеста вызывающего приложения, отвечающую за БД. Это и раньше можно было делать, но надо было код писать – а он всегда исполняется после require. Теперь можно сразу фэйлить старт, если вызывающая форма не expose’ит какие-то нужные фичи.

В общем то, недавний редактор JSON написан как раз отчасти чтобы это всё потестить.

Картинки

Когда рисовал схему паб/саба, внезапно нашлось три картинки. Кажется, не публиковал – и напрочь забыл, по какому случаю вообще их рисовал. Интересно, двигательная активность в сочетании с провалами в памяти ггг.

unnamed1 unnamed (1) unnamed (2)

Каникулы кончились, на дворе адище, русский зима, –30. А я дома в трусах и у меня внезапно ядовитый паслён Solanum pseudocapsicum мало того, что зацвёл, но ещё и ягодки будут.

В общем, сдержанно-оптимистичный пост, да.

Profile

ermouth: (Default)
ermouth

September 2017

S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 24th, 2017 04:56 am
Powered by Dreamwidth Studios