Как мы управляем конфигурациями в Pics.io

в 12:11, , рубрики: Без рубрики

configuration
В конце 2012 мы с ребятами собрались сделать сумасшедшую штуку – засунуть в браузер RAW конвертер, фотошоп и добавить туда возможность совместной работы над фотографиями. С технической стороны мы практически все проверили: технологии, которые позволяли все это воплотить, были сырыми, иногда требовали включения их в настройках браузера… но они были. Мы назвали это Pics.io и начали.

У нас была пачка прототипов/proof-of-concept, простыни кода с огромным количеством хардкодов. Мы решили, что нужно все это объединить в один большой продукт, который будет полностью покрывать рабочий процесс фотографа: придумали архитектуру, написали каркас, начали делать функциональность.

Пришло время пустить первых пользователей. Очень быстро обнаружилось, что они хотят нашу идею, но не хотят пользоваться тем, что мы напрограммировали. У нас не было иллюзий на этот счет — нельзя напедалить фотошоп за полгода. Еще некоторое время мы пытались добавлять в Pics.io новые функции. Пользователи приходили, регистрировались, но возвращались только, чтобы поглядеть, как у нас дела. Стало понятно, что даже early adopters нужен продукт, которым они могут пользоваться.

Мы решили попробовать сделать отдельный сервис, который можно было бы использовать прямо после релиза и который бы приносил пользу. Так появился live.pics.io, сервис для голосового обсуждения фотографий онлайн. Мы уже писали статью о технических деталях здесь на Хабре. Несмотря на большое количество проблем с относительно новой технологией WebRTC, эксперимент понравился как нам, так и нашим пользователям.

Тогда мы подумали, что мы можем разделить Pics.io на три более простые части и работать над ними отдельно:

  • Edit.pics.io для редактирования изображений
  • Raw.pics.io для конвертации RAW форматов
  • Live.pics.io для обсуждения и совместной работы

Затем, связав эти сервисы между собой при помощи инструментов DAM (Digital Assets Management) и добавив учетные записи пользователей, мы получили «большой» (как мы его называем между собой) Pics.io. Который, уже в свою очередь, позволит достичь нашей цели — стать универсальным пакетом для обработки фотографий в браузере. Итого, мы получили четыре самостоятельных продукта, каждый из которых предназначен для выполнения задач определенного сегмента пользователей.

Дальше — больше. Мы всегда хотели быть там, где находятся наши пользователи. Сперва нам казалось, что наши пользователи в интернете, поэтому мы будем строить все в браузере. Дальнейший анализ показал, что интернет — это слишком широкое понятие, и его тоже нужно сегментировать. Так мы нашли наших пользователей в Facebook, Chrome OS, mobile и конечно же в web. Итак, четыре продукта на четырех платформах. Получается шестнадцать возможных конфигураций. Не слабо, мягко говоря. У нас в команде, конечно, есть кое-какой опыт, но это действительно крутая задача, которую нам очень хотелось решить.

Вести шестнадцать разных продуктов параллельно это явно неподъемная задача для команды из семи человек. А что если это не отдельные продукты, а просто конфигурации деплоймента набора компонентов? Ага! Вот она вся сила configuration management!

Итак, что у нас есть:

  • команда из семи человек
  • шестнадцать продуктов
  • куча собственного и open-source’ного кода на все случаи жизни (начиная от вывода логов и заканчивая параллельной обработкой raw форматов)

Вся эта история привела нас к довольно любопытной архитектуре приложения и интересным решениям в configuration management. Мне кажется, что опыт, которым мы собираемся поделиться, будет интересен всем, кто занимается разработкой сложных веб-приложений.

Как мы управляем конфигурациями в Pics.io
Самое главное, чего мы хотели добиться — это заставить все части проекта максимально использовать одну кодовую базу. Фиксы и изменения должны сразу попадать и в микро-сервисы, и становиться частью большого приложения. Процедура деплоймента при этом должна быть максимально простой, а при желании мы должны иметь возможность добавлять наши куски в любые сторонние сервисы. Как же из кучи разрозненных кусков и скриптов собрать целостную инфраструктуру, внутри которой легко работать?

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

Дальше мы разбили наши полотна кода на минимальные модули, зависимости между которыми, разрешаются с помощью RequireJS. C одной стороны, это повлекло за собой долгую работу по рефакторингу большей части исходного кода и появлению новых модулей, с другой — позволило убрать зависимости, которых не должно быть, и достаточно сильно понизить связанность внутри проекта.

Естественно, такой подход потребовал особого взаимодействия между модулями, и большинство из них имеют ряд ограничений (для того, чтобы быть использоваными в любом продукте). Например, мы совершенно не имеем возможности использовать в некоторых модулях Backbone-модели, так как они могут встраиваться, например, в raw.pics.io, который вовсе не использует Backbone. Но подобные ограничения не особо нам мешают, а наоборот отделяют высокоуровневые UI модули от общего ядра и не засоряют его лишними зависимостями.

Собирать модули нам помогает RequireJS. Для каждого сервиса существует свой конфигурационный файл, который описывает все зависимости между модулями. Потом с помощью билдера r.js Grunt генерирует нужные билды и единственное, что нам нужно — содержать наши модули «в чистоте» и собирать новый продукт из готовых кусочков с помощью конфигов. Таким образом, разрабатывая, мы не думаем о том, в какой продукт попадет фича, так как она попадет во все продукты сразу.

Естественно, такой подход потребовал более сложного тестирования — перед каждым релизом мы перепроверяем несколько продуктов вместо того, чтобы проверить только один, но использование общих исходников сильно упростило разработку, хоть и усложнило конфигурацию и тестирование. Хотя проверить свои продукты лишний раз никогда не помешает. ;)

Скрипты для сборки и деплоймента написаны, но мы всё еще деплоимся вручную. Следующий наш шаг — это CI, для которого мы выбрали Strider-CD, который запустит деплоймент на тестовый/продакшн сервер и/или подскажет нам, когда что-то пошло не так.

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

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

Автор: yetithefoot

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js