Главная страница
Навигация по странице:

  • Единственная версия

  • Сценарий: несколько доступных версий

  • Правило «единственной версии»

  • (Почти) полный отказ от долгоживущих ветвей

  • А что насчет ветвей версий

  • Монолитные репозитории

  • Делай как вGoogle


    Скачать 5.77 Mb.
    НазваниеДелай как вGoogle
    Дата31.05.2022
    Размер5.77 Mb.
    Формат файлаpdf
    Имя файлаDelay_kak_v_Google_Razrabotka_programmnogo_obespechenia_2021_Tom.pdf
    ТипДокументы
    #559735
    страница42 из 69
    1   ...   38   39   40   41   42   43   44   45   ...   69
    336
    Глава 16. Управление версиями и ветвями более явными и гарантировать их соблюдение на этапе выполнения фиксации. Это гибкий подход: владение определяется простым текстовым файлом, не привязанным к физическому разделению репозиториев, который легко обновить при переходе команд или реструктуризации организации.
    Единственная версия
    Невероятные возможности масштабирования одной только системы Piper не могли бы обеспечить такого уровня сотрудничества, на которое мы рассчитываем. Как уже говорилось выше, управление версиями — это еще и политика. В дополнение к нашей
    VCS, еще одной ключевой особенностью политики управления версиями в Google является идея так называемой «единственной версии». Она дополняет идею «един- ственного источника истины», которую мы рассмотрели выше, и гарантирует, что разработчик всегда знает, какая ветвь и какой репозиторий являются источником ис- тины для него. То есть фактически эта идея требует, чтобы «для каждой зависимости в репозитории имелась только одна версия»
    1
    . Для сторонних пакетов это означает, что в репозитории в устойчивом состоянии может находиться только одна версия этого пакета
    2
    . Для внутренних пакетов это означает невозможность ветвления без переупаковки или переименования, то есть исключение любой возможности смеши- вания оригинала и его новой версии (производной) в одном проекте. Это мощная особенность нашей экосистемы, и в ней очень мало пакетов с ограничениями вида
    «если вы подключили пакет A, то не можете подключить пакет B».
    Идея наличия единственной копии в единственной ветви в единственном репози- тории, играющей роль источника истины, интуитивно понятна, но имеет некоторые тонкости применения. Рассмотрим сценарий, в котором есть монолитный репозито- рий (что, казалось бы, соответствует требованию наличия единственного источника истины), в главную ветвь которого попали несколько версий библиотек.
    Сценарий: несколько доступных версий
    Представьте, что команда обнаруживает ошибку в коде общей инфраструктуры (на- пример, Abseil или Guava), но вместо ее исправления на месте решает создать новую версию этой инфраструктуры и внести в нее изменения, исправляющие ошибку, — без переименования библиотеки или любых ее символов. Эта команда сообщает соседним командам: «Привет, мы создали улучшенную версию Abseil, пользуйтесь ею». Несколько других команд создают библиотеки, полагающиеся на эту новую производную версию.
    1
    Например, во время операции обновления в репозитории могут быть зарегистрированы две версии, но если разработчик добавляет новую зависимость в существующий пакет, у него не должно быть возможности выбирать версию зависимости.
    2
    Часто нам это не удается, потому что внешние пакеты иногда имеют закрепленные копии своих зависимостей, входящих в их версию исходного кода. Подробнее о возможных по- следствиях в главе 21.

    Управление версиями в Google
    337
    Как будет показано в главе 21, это решение создает опасную ситуацию. Если какой- то проект в кодовой базе будет зависеть сразу от обеих версий Abseil, исходной и производной, то в лучшем случае сборка не выполнится, а в худшем случае — воз- никнут трудные для понимания ошибки времени выполнения, возникающие из-за связывания кода с двумя несовместимыми версиями одной и той же библиотеки.
    Производная версия фактически добавила раскраску/разделение в базу кода. На- бор переходных зависимостей для любой заданной цели должен включать в себя ровно одну копию библиотеки. Любая ссылка, добавленная из раздела исходной версии в соответствующий раздел производной версии, почти наверняка нарушит работоспособность кода. В конечном итоге такая простая операция, как «добавление новой зависимости», может потребовать выполнения всех тестов для всей кодовой базы ради соблюдения требований этого разделения. Это дорого, утомительно и плохо масштабируется.
    Иногда можно применить грубый прием жесткого кодирования и добиться, что- бы выполняемый файл работал правильно. В Java, например, есть относительно стандартная практика, называемая затенением (
    https://oreil.ly/RuWX3
    ), при ко- торой вы меняете имена внутренних зависимостей библиотеки, чтобы скрыть их зависимости от остальной части приложения. При работе с функциями это технически разумно, даже если теоретически это выглядит немного грубо. При работе с типами, которые можно передавать из одного пакета в другой, решения на основе затенения не работают ни в теории, ни на практике. Насколько нам из- вестно, для типов не действуют никакие технологические уловки, позволяющие нескольким изолированным версиям библиотеки действовать в одном двоичном файле, например попытка использовать несколько версий любой библиотеки, предлагающей тип словаря (или любую конструкцию высокого уровня), обречена на неудачу. Практика затенения и связанные с ней подходы устраняют основную проблему: необходимость использования нескольких версий одной и той же за- висимости. (Подробнее о том, как минимизировать опасность при нескольких доступных версиях, в главе 21.)
    Любая система политик, допускающая использование нескольких версий в одной кодовой базе, способствует проникновению в код дорогостоящих несовместимостей.
    Возможно, вам удастся на время решить эту проблему (нам иногда это удается), но в целом любая ситуация с несколькими версиями может привести к большим про- блемам.
    Правило «единственной версии»
    Глядя на этот пример и описание модели единого источника истины, можно по- нять и оценить всю глубину, казалось бы, простого правила управления версиями и ветвями:
    У разработчиков не должно быть выбора, «от какой версии компонента им за- висеть».

    338
    Глава 16. Управление версиями и ветвями
    Для простоты это правило можно назвать «правилом единственной версии».
    На практике «единственная версия» не является незыблемой
    1
    , но формулировка ограничения в выборе версий для добавления новой зависимости задает верное на- правление в работе с версиями.
    Отдельному разработчику отсутствие выбора может показаться малопонятным пре- пятствием. Однако для организаций это отсутствие выбора — важный компонент эффективного масштабирования. Согласованность имеет огромное значение на всех уровнях организации, от обсуждения общей согласованности в компании до обеспечения возможности согласованного использования «узких мест».
    (Почти) полный отказ от долгоживущих ветвей
    В наше правило о единственности версии заложено несколько глубоких идей. Глав- ная из них: количество ветвей разработки должны быть минимальным, и эти ветви должны существовать очень короткое время. Это следует из большого количества работ, опубликованных за последние двадцать лет, от описаний процессов гибкой разработки до результатов исследований DORA по разработке в главной ветви и даже уроков Phoenix Project
    2
    по «сокращению незавершенного производства».
    Представление незавершенной работы как ветви разработки еще больше усиливает требование выполнять работу небольшими шагами и регулярно проводить фиксацию изменений в главную ветвь.
    В качестве контрпримера: в сообществе разработчиков, которое в значительной степени зависит от долгоживущих ветвей разработки, нетрудно представить возврат к возможности выбора.
    Представьте такой сценарий: команда, занимающаяся развитием инфраструктуры, работает над новым виджетом, который лучше старого. Волнение нарастает: из других проектов, запущенных недавно, команде поступают вопросы: «Можем ли мы использовать ваш новый виджет?» Но не стоит торопиться «разрешать» за- висимость от нового виджета, если он существует только в параллельной ветви.
    Помните: у новых проектов не должно быть выбора при добавлении зависимо- стей. Этот новый виджет должен быть зафиксирован в главной ветви, недоступен для использования, пока не будет полностью готов, и по возможности скрыт от других разработчиков с помощью правил видимости. Либо две версии виджета должны быть спроектированы так, чтобы они могли сосуществовать в одних и тех же программах.
    1
    Например, бывает невозможно обновить внешнюю или стороннюю библиотеку и весь код, использующий ее, в одном атомарном изменении. Поэтому часто приходится добавлять новую версию библиотеки, запрещать новым пользователям добавлять за- висимости от старой и постепенно переводить код с использования старой библиотеки на новую.
    2
    Бер К., Ким Дж., Спаффорд Дж. Проект «Феникс». Роман о том, как DevOps меняет бизнес к лучшему. М.: Эксмо, 2014. — Примеч. пер.

    Управление версиями в Google
    339
    Отметим, что уже есть свидетельства того, насколько правило единственной версии важно для отрасли. В книге «Ускоряйся!»
    1
    и в самых последних отчетах «State of
    DevOps» ассоциации DORA указывается, что существует тесная взаимосвязь между разработкой в главной ветви и эффективностью софтверных организаций. Компания
    Google — не единственная организация, которая обнаружила это. Конечно, мы не всегда получали ожидаемые результаты, развивая эту политику, просто нам казалось, что никакие другие подходы не позволяют достичь желаемого результата. Однако результаты, полученные в DORA, безусловно, соответствуют нашему опыту.
    Наши политики и инструменты для крупномасштабных изменений (глава 22) при- дают дополнительную важность идее разработки в главной ветви: обширные (по- верхностные) изменения, которые применяются ко всей кодовой базе, уже стали массовым (часто утомительным) явлением при изменении всего, что находится в главной ветви. Наличие неограниченного количества дополнительных ветвей разработки, которые могут потребовать синхронного рефакторинга, повлекло бы гигантские затраты на выполнение изменений такого рода, обусловленные необхо- димостью поиска в постоянно расширяющемся наборе скрытых ветвей. А в модели распределенной VCS может даже оказаться невозможным идентифицировать все такие ветви.
    Конечно, наш опыт не универсален. Вы можете оказаться в необычной ситуации, требующей создания долгоживущей ветви разработки, существующей параллельно главной ветви (и регулярно объединяющейся с ней).
    Такие сценарии должны быть редкими, и их следует расценивать как дорогостоящие.
    Из примерно 1000 команд, которые работают в монолитном репозитории Google, лишь несколько имеют подобные ветви разработки
    2
    . Обычно эти ветви создаются по очень конкретной (необычной) причине, например: «У нас необычное требование к длительному сохранению совместимости». Часто такой причиной является обес- печение совместимости по данным между версиями: код, читающий и записываю- щий файлы в некотором формате, должен продолжать использовать согласованное представление о формате и после внесения изменений в него. В других случаях причиной может стать сохранение совместимости API, например если при выпуске новой версии нужно гарантировать сохранение работоспособности более старой версии клиента микросервисов при работе с новым сервером (или наоборот). Такая гарантия может оказаться очень сложным требованием, и вы не должны легкомыс- ленно давать долгосрочные гарантии, работая над активно развивающимся API, чтобы период времени их действия не начал расти вопреки вашим желаниям. Зави- симость кода от времени в любой ее форме обходится дорого. Внутренние службы
    Google редко дают такие гарантии
    3
    . Мы также здорово выигрываем, ограничивая
    1
    Форсгрен Н., Хамбл Дж., Ким Дж. Ускоряйся! Наука DevOps. Как создавать и масштаби- ровать высокопроизводительные цифровые организации. Интеллектуальная литература,
    2020. — Примеч. пер.
    2
    Точно подсчитать довольно трудно, но таких команд меньше 10.
    3
    Другое дело — облачные интерфейсы.

    340
    Глава 16. Управление версиями и ветвями потенциальную асимметрию версий, обусловленную нашим «горизонтом сборки»: все службы в продакшене должны повторно собираться и развертываться не реже, чем один раз в шесть месяцев (обычно гораздо чаще).
    Мы уверены, что есть и другие ситуации, когда могут понадобиться долгоживущие ветви разработки. Просто постарайтесь использовать их как можно реже. Если вы решите использовать у себя другие инструменты и методы, описанные в этой книге, то многие из них будут оказывать давление на долгоживущие ветви разработки.
    Инструменты и средства автоматизации, прекрасно работающие с главной ветвью и терпящие неудачу (или требующие больших усилий) при работе с ветвью разра- ботки, могут помочь разработчикам не отставать от жизни.
    А что насчет ветвей версий?
    Многие команды в Google подходят к использованию ветвей избирательно. Если вы собираетесь выпускать новые версии ежемесячно и продолжать работу над следу- ющей версией, вполне разумно создать ветвь версии. Точно так же, если вы собира- етесь поставлять устройства клиентам, важно точно знать, какая версия находится в «эксплуатации». Будьте внимательны и рассудительны при создании таких ветвей и не планируйте объединять их с главной ветвью. Наши команды определяют все- возможные политики в отношении ветвей, учитывая, что лишь немногие достигли частой периодичности выпуска, которую обещает методология непрерывного раз- вертывания (глава 24), избавляющая от необходимости или желания создавать ветви версий. В целом, как показывает наш опыт, ветви версий не влекут за собой больших затрат (или, по крайней мере, никаких заметных затрат, кроме дополнительных за- трат на поддержку VCS).
    Монолитные репозитории
    В 2016 году мы опубликовали (часто цитируемый и широко обсуждаемый) документ о подходе компании Google к монолитным репозиториям
    1
    . Главное преимущество монолитных репозиториев — простота следования правилу единственной версии: нарушить это правило в репозитории сложнее, чем следовать ему. У нас нет процес- са, определяющего, какие версии являются официальными или какие репозитории наиболее важны. Инструменты сборки (глава 23) тоже не требуют определения важных репозиториев. Повысить эффективность внедрения новых инструментов и оптимизаций помогает согласованность. В целом инженеры могут видеть действия коллег и использовать эту информацию при выборе решений в своем коде и проекте своей системы.
    Учитывая все это и нашу веру в преимущества правила единственной версии, воз- никает вопрос: является ли использование монолитного репозитория самым верным
    1
    Potvin R., Levenberg J. Why Google stores billions of lines of code in a single repository.
    Communications of the ACM, 59 No. 7 (2016): 78–87.

    Монолитные репозитории
    341
    подходом. Для сравнения: сообщество открытого ПО с успехом использует подход, основанный на применении кажущегося бесконечным множества некоординируемых и несинхронизируемых репозиториев проектов.
    Если отвечать кратко, то мы не думаем, что подход на основе монолитного репозито- рия, как мы его описали, является идеальным для всех. Продолжая параллель между форматом файловой системы и VCS, легко представить выбор между использовани- ем 10 дисков для одной большой логической файловой системы или 10 небольших файловых систем, доступ к которым осуществляется раздельно. В мире файловых систем оба подхода имеют свои плюсы и минусы. С технической точки зрения оценка выбора файловой системы может зависеть от устойчивости к сбоям, ограничений размеров файлов, характеристик производительности и т. д. Оценки с точки зрения удобства, скорее всего, в большей степени будут зависеть от возможности ссылать- ся на файлы через границы файловой системы, добавлять символические ссылки и синхронизировать файлы.
    Аналогично определяется предпочтительность монолитных репозиториев или кол- лекций более мелких репозиториев. Всякое конкретное решение о том, как хранить исходный код (то есть файлы), легко оспорить, и в некоторых случаях особенности организации и рабочего процесса будут иметь большее значение при выборе храни- лища кода, чем другие аргументы. Это решение вы должны принять самостоятельно.
    Важна не сосредоточенность кода на монолитном репозитории, а стремление макси- мально придерживаться принципа единственной версии: у разработчиков не должно быть выбора при добавлении зависимости в библиотеку, которая уже используется в организации. Нарушение правила единственной версии приводит к необходимо- сти обсуждения политики слияния, появлению ромбовидных зависимостей, потере времени и сил.
    Инструменты программной инженерии, включая VCS и системы сборки, предостав- ляют механизмы для комбинирования разрозненных и монолитных репозиториев, чтобы обеспечить согласование фиксаций и анализ графа зависимостей как в моно- литном репозитории. Подмодули Git, система сборки Bazel с внешними зависимо- стями и подпроекты CMake позволяют современным разработчикам синтезировать нечто, имитирующее поведение монолитного репозитория без свойственных ему затрат и недостатков
    1
    . Например, с разрозненными мелкими репозиториями лег- че работать с точки зрения масштабирования (в Git часто возникают проблемы с производительностью после нескольких миллионов фиксаций и наблюдается склонность к замедлению процедуры клонирования при наличии в репозитории больших двоичных артефактов) и размера хранилища (метаданные VCS могут постепенно накапливаться, особенно если в VCS имеются двоичные артефакты).
    Мелкие репозитории в объединенном виртуальном монолитном репозитории (VMR,
    Virtual-MonoRepo) могут упростить изоляцию экспериментальных или секретных
    1
    Мы не думаем, что это легко реализовать, но идея хранения зависимостей в разных репо- зиториях и организации виртуального монолитного репозитория явно витает в воздухе.

    342
    Глава 16. Управление версиями и ветвями проектов, обеспечивая соблюдение принципа единственной версии и предоставляя доступ к общим утилитам.
    Таким образом, если все проекты в организации имеют одинаковые требования к секретности, законности, конфиденциальности и безопасности, используйте монолитный репозиторий
    1
    . В противном случае лучше отдать предпочтение функ- циональности монолитного репозитория, но реализовать ее другим способом. Если у вас есть возможность управлять отдельными репозиториями и придерживаться принципа единственной версии или ваша рабочая нагрузка достаточно разобщена, чтобы использовать отдельные репозитории, примените коллекцию репозиториев.
    В противном случае — создайте что-то вроде VMR.
    В конце концов, выбор формата файловой системы действительно не так важен, как то, что вы в нее пишете.
    1   ...   38   39   40   41   42   43   44   45   ...   69


    написать администратору сайта