Когда мы говорим о проектах с открытым исходным кодом, то частенько, как само собой разумеющееся, опускаем тему инфраструктуры распространения дистрибутива проекта. Но сегодня, когда у нас есть вагон и тележка операционных систем и расширений к основному проекту, это и есть та самая подводная часть айсберга.
На примере веб-сервера Angie расскажу вам про инфраструктуру проекта с открытым исходным кодом в формате интервью, которое я взял у команды в режиме чайка менеджера в пятницу вечером. С учетом того, что команда делает опен-сорс проекты последние 15 лет, получилось, как нам кажется, интересно.
Для работы с базами данных Golang предлагает пакет database/sql, который является абстракцией над программным интерфейсом реляционной базы данных. С одной стороны пакет включает мощную функциональность по управлению пулом соединений, работе с prepared statements, транзакциями, интерфейсом запросов к базе. С другой стороны приходится написать немалое кол-во однотипного кода в веб приложении для взаимодействия с базой данных. Библиотека go-gad/sal предлагает решение в виде генерации однотипного кода на основе описанного интерфейса.
Набор библиотек для разработки CMS медиа издания практически ничем не отличается от любого другого приложения. На примере приложения для Ленты и Ведомостей мы решили прокомментировать выбор каждой библиотеки. Описание составлено в формате обсуждения каждого гема.
Мне довелось поработать (fb) в интернет издании Лента.ру. Пройти путь от разработчика до технического директора. Успешно реализовать полноценный перезапуск. Попутно занимаясь подобными проектами меньшего масштаба. Теперь мы с командой занимаемся подготовкой перезапуска интернет газеты Ведомости (fb).
Расскажу о разработке проектов медиа изданий. Галопом по Европам, зацепимся за основные темы. К вам, дорогие читатели, просьба набросать вопросы, которые необходимо раскрыть более детально. Например мой коллега планирует написать о развёртывании системы, отказоустойчивой схеме работы сайта.
В ходе разработки серверной части сервиса загрузки файлов на Golang родилось отдельное приложение – pavo. В задачи приложения входит загрузка целых файлов, по одному или несколько за раз, кусочная загрузка файла(chunked upload), конвертер изображений. Реализована загрузка данных через multipart/form-data и загрузка файла в бинарном виде в теле запроса. Для работы в production окружении используется nginx для авторизации и обработки медленных соединений. В качестве клиентской библиотеки можно использовать jQuery File Uploader.
В Rails-приложениях с богатой клиентской частью используют шаблоны на стороне клиента. Если эти шаблоны обрабатываются с помощью Asset Pipeline, то встаёт вопрос о способе обращения к ним. В production-окружении путь до файла складывается из его имени и md5-хеша. Один из вариантов получить нужный путь — обернуть JavaScript в препроцессор Erb, где будет доступен нужный хелпер <%= asset_path(path/to/template.html) %>
Маленькое расширение для FCGI::ProcManager, позволяющее обращаться к менеджеру fcgi процессов. Для связи сторонней программы с менеджером используется сокет.
Подводные камни
Модуль FCGI::ProcManager используется для порождения обработчиков входящих запросов. Текущий процесс является менеджером. Со старта он порождает обработчиков (n_processes штук), далее он поддерживает их количество, следя за погибшими в бою. Для этих целей он использует wait. Тут и кроется проблемка. После того, как запущены потоки, менеджер, вызывая wait, блокируется. Достучаться до него можно только через сигналы. Исполнять в обработчике сигнала код нужно с умом и аккуратно, гонять там говнокод — нехорошо. А значит необходимо наладить другой канал связи.
Складывается впечатление, что стандарт синтаксиса шаблона – это то, что мы используем в качестве обрамления управляющих конструкций (скобочки, процентики, вопросики). Это неверно. Символы, в которые мы заключаем ту или иную запись шаблона, это всего лишь способ связать данные с логикой. Тут сложно установить какой-то стандарт. А вот логика воспроизведения той или иной конструкции должна быть заранее оговорена, и именно тогда мы сможем делать совместимые друг с другом шаблоны для разных языков программирования.
Но сегодня мы всё же поговорим про эти самые скобочки. Не забудем и про сигилы для переменных.
Примеров ограничения конструкций шаблонизатора превеликое множество. Угловые, фигурных, квадратные, круглые скобки в сочетаниях друг с другом и с такими символами как %, ?, $, #… В общем вы знаете, что специальных символов достаточно много, а комбинаций их использования еще больше.
Для затравки и предметного обсуждения нужна точка отсчета. В шаблонизаторе нас интересуют поддерживаемые типы конструкций, способ их обрамления, какие-то возможности (препросмотр без компиляции).
Основные типы конструкций для управления выводом в шаблоне:
Переменные.
Условные операторы.
Операторы циклов.
Инклуды, блоки.
Наследование.
Уже этих конструкций с лихвой достаточно, чтобы реализовать большинство проектов. И само собой мы их видим почти в каждом шаблонизаторе, с теми или иными отличиями и особенностями. Но давайте поразмыслим, какие в теории возможности они должны позволять использовать, и как эти реализации должны выглядеть в идеале.
Перестали ли вы слышать от новичков вопрос: «какой выбрать шаблонизатор?». Не думаю.
Единственное что можно с уверенностью сказать, что периодически некоторые решения становятся популярны в определенных кругах, но они по большей части органичение их области применения, это язык программирования. Перечислять плюсы существования каких-либо стандартов не нужно. Все понимают, «от этого хорошо будет всем». Придумать, закрепить, применить их – вот эта задача, далеко не тривиальная, но ведь решаемая.
Мы начали с ( javascript шаблонизатора), что использовать один и тот же шаблон на стороне клиента и на стороне сервера, это удобно. Готовых рализаций такого подхода кот наплакал. Кровь приливает к голове, мы решаемся написать своё решение.
Обрисуем исходные данные и задачу
Пусть у нас есть шаблоны, от нашего шаблонизатора. На сервере они обрабатываются perl'ом. В конечном итоге мы хотим некоторые из имеющихся шаблонов, или их частей, не вынесенных в отедельный файл, использовать на стороне клиента. Необходимо с минимальными затратами(в потерере функциональности) воспроизвести процедуры генерации html. В результате обработки шаблонов, мы хотим получить наборы предварительно указанных шаблонов и блоков, оформленных в виде библиотеки javascript. Сказано – сделано.
В наше время существует уже немалое количество таковых, не правда ли? Они даже неплохо справляются со своей работой, если надо, к примеру, сформировать HTML за сотые доли секунды – это довольно быстро, и пользователь не чувствует этой задержки. И почему же мы все не кидаемся вовсю использовать шаблонизацию на стороне клиента? Ну вот к примеру несколько пунктов:
– генерировать страницу (бОльшую её часть) становится таки уже накладно;
– если у вас используется смешанная шаблонизация (шаблоны и на javascript, и на вашем любимом скриптовом языке), то возникнет ситуация, когда они у вас дублируются;
Вот о втором пункте мне бы и хотелось поговорить, его решение прямо повлияет на решение первой проблемы — производительности.