среда, 25 января 2017 г.

Про Docker и Ruby on Rails sprockets and precompiled assets.

Рельсы идут не тем путем.

По-хорошему монолит на рельсах нужно дробить, а то получается 1С:Бухгалтерия, со всеми включенными галочками по-умолчанию. В данном случае умолчания в рельсах слишком greedy.

Взять вот sprockets. Его задача вообще один раз запуститься, минифицировать css и js, и замолчать навеки. При этом он требует кучу разнообразных зависимостей типа execjs, nodejs или v8 от гугла в качестве движка минификации.

Но что делает фреймворк? Sprockets включают в Gemfile, он грузится вместе с полезным кодом, занимает кучу места, мешается под ногами и заставляет программиста танцевать с бубном вокруг задач связанных с деплоем!

Как было бы делать правильно? Минификацию JS и CSS отрезать и делать ее опциональной, отдельной утилитой, если хотите, в составе рельс. Такой же как и rake. Назвать ее minirake и дать набор ключей для запуска. Но! У нас по всему фреймворку нужно протянуть новые названия файлов, которые генерятся при минификации! Потому что как же нам еще разделить код и данные? Короче, считаю это ошибкой дизайна, когда оптимизация НАВЯЗАНА разработчику, то есть для 99% сайтов она будет делаться ПРЕЖДЕВРЕМЕННО.

Тоже самое можно сказать и про turbolinks. Во-первых очень мало народу понимает как оно в реальности работает, соответственно каких косяков ожидать. Это та же самая, мать ее, premature optimization. Всегда гораздо сложнее упрощать что-то сложное, чем добавлять и ускорять по мере необходимости.

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

И вот здесь детальнее, о чем я имею в виду https://blog.red-badger.com/blog/2016/06/22/docker-and-assets-and-rails-oh-my

вторник, 24 января 2017 г.

Вот сегодня запиливая очередной апдейт в простеньком Ruby on Rails сайте я понял

Для чего подходит хорошо Ruby on Rails?

Для быстрого bootstrap, quick'n'dirty прототипа приложения. Чтобы всю схему с базой данных запилить за 5 секунд с шаблонами и простой управлялкой. Потому что ты уже знаешь все косяки и подводные камни и названия библиотек, все это проходит за пять секунд.

Но! Разрабатывать долго и сложно на Рельсах превращается в филиал ада на Земле. Очень много магии, механизмы кеширования как часть фреймворка тесно переплетенная с логикой. А чего стоит интеграция с jQuery и вот эта вот магия с .js.erb, .json.jbuilder ? WTF? Вот так сидишь и смотришь на очередной суперпупер gem который делает за тебя весь кодинг. А I18n? А управление очередями, а Live Stream или как это сейчас называется?

Всего этого не знаешь и не замечаешь, пока не пробуешь изучать функциональные языки на подобие Clojure.

Изучение Clojure абсолютно точно делает тебя лучше, умнее, быстрее. Применение функциональных паттернов в Руби делает код более изящным и читаемым и разделение смыслов более явным. 

Вот сегодня я почти полностью ушел от sqlite3 в пользу плоского YAML для сайта. Потому что зачем? В Clojure подобный фукнционал несет в себе формат EDN.

Вот например, отображать только те комментарии у которых есть поле коммент. Как это делается в базе, типа sqlite3, выборкой select * where comment is not NULL. Как делается через YAML? 

myfile = YAML.load(File.read('my.yaml'))

затем уже 
myfile["myarray"].reject{|i| !i.logo} 

оставит в коллекции только те значения, которые нужны. Минус задержка на обращение к базе, код автоматически становится быстрее, минус еще одна зависимость, плюс к управляемости данными. Данные же сейчас доступны в простом текстовом редакторе, вам для этого не нужен никакой SQL клиент! Минус сложность связанная с языком запросов, он здесь становится просто не нужен!

И главное, программа стала проще.

Миграции как в рельсах для Clojure

Below is a list of all the popular migration libraries that are currently available:
  • Drift - Drift is a migration library written in Clojure. Drift works much like Rails migrations where a directory in your project contains all of the migration files. Drift will detect which migration files need to be run and run them as appropriate.
  • Lobos - Lobos is a SQL database schema manipulation and migration library written in Clojure. It currently support supports H2, MySQL, PostgreSQL, SQLite and SQL Server.
  • Ragtime - a general migration framework, with an implementation for database migrations.
  • Joplin - Joplin is a library for flexible datastore migration and seeding
Luminus http://www.luminusweb.net/docs/migrations.md#popular_migrations_alternatives

Хотя лично я справился и с Ragtime.
Забавный факт, database.yml и вообще поддержка баз данных гвоздями вколочена в Rails. Что печалит, конечно.

Нужно танцевать с бубном чтобы выключить процессинг database и ActiveRecord. Такие дела.