# Этот релиз точно будет LTS Небольшой доклад, способный растрогать любого. --- ## Х сделано неправильно, давайте исправим до LTS Давайте разберемся с X. Что с ним не так?<!-- .element: class="fragment" data-fragment-index="1" --> --- ## Так быть не должно, мы считаем это багом Это существующее поведение, на него кто-то может полагаться.<!-- .element: class="fragment" data-fragment-index="1" --> --- ## Я спросил у Delivery и Presale, они ок Мы не знаем всех наших пользователей и их сценариев использования.<!-- .element: class="fragment" data-fragment-index="1" --> --- ## Я хорошо подумал и решил, что ничего не сломается Мы хорошо подумали перед тем, как:<!-- .element: class="fragment" data-fragment-index="1" --> * закрыть символы,<!-- .element: class="fragment" data-fragment-index="2" --> * потом перед тем, как открыть их,<!-- .element: class="fragment" data-fragment-index="3" --> * и перед тем, как закрыть снова.<!-- .element: class="fragment" data-fragment-index="4" --> --- И еще над кучей вещей. Практика показывает, что даже неломающим с виду изменением мы иногда ломаем пользователя. Что уж говорить о том, что заведомо меняет поведение. --- ## Раз мы все равно это делаем, то почему бы не сейчас? Возможность ошибок не отменяет гарантий совместимости.<!-- .element: class="fragment" data-fragment-index="1" --> Мы не ломаем пользователя намеренно. Но, если сломали, то чиним это в багфикс-релизе.<!-- .element: class="fragment" data-fragment-index="2" --> --- ## Значит, мы не можем ничего исправить? Вовсе нет. Мы исправляем совместимо, где возможно.<!-- .element: class="fragment" data-fragment-index="1" --> Мы меняем поведение с мажорной версией, где по-другому нельзя.<!-- .element: class="fragment" data-fragment-index="2" --> --- ## Значит, этого не будет в следующем релизе? * Мы предоставим новое поведение под флагом совместимости.<!-- .element: class="fragment" data-fragment-index="1" --> * Его можно включить в проекте, если там это требуется.<!-- .element: class="fragment" data-fragment-index="2" --> * Дефолтом это станет через несколько лет.<!-- .element: class="fragment" data-fragment-index="3" --> --- Да, мы хотим мотивировать к хорошим практикам и дать хороший дефолт. Но нет, это не делается по щелчку пальцев. --- ## А как же LTS? Мы хотим это в LTS. <..играет тревожная музыка, у главного героя флешбеки..><!-- .element: class="fragment" data-fragment-index="1" --> --- ## LTS и 2.X Раньше в тарантуле было разделение на серии релизов 2.X, поддерживаемые три месяца («на хрен не нужные») и LTS (1.10).<!-- .element: class="fragment" data-fragment-index="1" --> 2.X и 2.Y могли быть несовместимы. Быстрое развитие, но нет релиза для пользователя.<!-- .element: class="fragment" data-fragment-index="2" --> --- ## Серия 2 (2.10+) Мы взяли публичное обязательство поддерживать серии релизов с эволюцией фич. Что это значит?<!-- .element: class="fragment" data-fragment-index="1" --> --- ## 2, 2.10 и 2.10.0 Мы поддерживаем серию 2. Серия 2 является предметом поддержки. Все релизы этой серии совместимы.<!-- .element: class="fragment" data-fragment-index="1" --> Серия 2 распадается на фичсеты: 2.10, 2.11 и&nbsp;т.&nbsp;д.<!-- .element: class="fragment" data-fragment-index="2" --> В рамках фичсетов есть «замороженные» точки: релизы 2.10.0, 2.11.2, ...<!-- .element: class="fragment" data-fragment-index="3" --> --- ## Что за магия? Раз 2.7 и 2.8 несовместимы, то 2.10 и 2.11 тоже. Добавление новой функциональности не обязано быть несовместимым изменением. И как правило не является.<!-- .element: class="fragment" data-fragment-index="1" --> «Опасность» поломки существующего кода из-за новой фичи ниже, чем из-за багфикса.<!-- .element: class="fragment" data-fragment-index="2" --> Мы можем развивать серию 2 как 2.10, 2.11, 2.12 и так далее.<!-- .element: class="fragment" data-fragment-index="3" --> --- ## Но есть же semver, принятые практики... В точку! Посмотрим на семантическое версионирование.<!-- .element: class="fragment" data-fragment-index="1" --> --- > Given a version number MAJOR.MINOR.PATCH, increment the: > > 1. MAJOR version when you make incompatible API changes > 2. MINOR version when you add functionality in a backwards compatible manner > 3. PATCH version when you make backwards compatible bug fixes --- Тезис «не ломаем текущее поведение» относится к мажорным релизам. Это одно из двух основных обязательств по поддержке: не ломать и чинить. Поэтому естественно сделать мажорную серию предметом поддержки. У нас нет обязательства не добавлять фич в серию релизов.<!-- .element: class="fragment" data-fragment-index="1" --> --- ## Это подмена понятий и де-факто отсутствие поддержки! Вопрос в том, что пользователь, который взял 2.10, хочет обновлений для 2.10 и не хочет ставить 2.11, потому что страшно.<!-- .element: class="fragment" data-fragment-index="1" --> Разберемся, в чем тут дело.<!-- .element: class="fragment" data-fragment-index="2" --> --- ## И в чем тут дело? * Не в semver, как мы уже видели.<!-- .element: class="fragment" data-fragment-index="1" --> * Может, в 1.5 vs 1.6 vs 1.7... наверное.<!-- .element: class="fragment" data-fragment-index="2" --> * Может, в 2.X vs 2.Y... тоже верно.<!-- .element: class="fragment" data-fragment-index="3" --> Или есть примеры в других продуктах?<!-- .element: class="fragment" data-fragment-index="4" --> --- ## Что у других? * Python 3 (кто-то запоминает миноры?).<!-- .element: class="fragment" data-fragment-index="1" --> * Curl 7 (вот тут уж точно никто).<!-- .element: class="fragment" data-fragment-index="2" --> * etcd 3.4 -> 3.5 (ага!) совместимы (а...).<!-- .element: class="fragment" data-fragment-index="3" --> * Go 1.<!-- .element: class="fragment" data-fragment-index="4" --> --- ## Но пользователь хочет вечный 2.10... А другой пользователь — вечный 2.11. Третий остановится на 2.12.<!-- .element: class="fragment" data-fragment-index="1" --> Вкладывая усилия в совместимость фичсетов, мы экономим усилия по мейнтенансу и поддержке.<!-- .element: class="fragment" data-fragment-index="2" --> --- ## ...и готов дать денег За поддержку, не за циферки. И ровно тот же пользователь попросит новых фич в 1.10.<!-- .element: class="fragment" data-fragment-index="1" --> Да, мы поддерживаем пользователя: расследуем проблемы, подпираем костылем и планируем обновление.<!-- .element: class="fragment" data-fragment-index="2" --> --- ## Но ведь все-таки должен быть LTS? Все серии релизов являются сериями с длительной поддержкой, именно поэтому их *можно* использовать.<!-- .element: class="fragment" data-fragment-index="1" --> Проблема не-LTS серий в том, что их нельзя взять в проект: вы фиксируете версию, и через несколько месяцев вам просто некуда обновляться.<!-- .element: class="fragment" data-fragment-index="2" --> --- Другая проблема в том, что пользователь хочет фич, а мы его фиксируем на 2.10 LTS, куда фичи не попадают. От разделения на LTS и не-LTS нет пользы, только вред.<!-- .element: class="fragment" data-fragment-index="1" --> --- ## Так что с проблемой X? * Мы поняли, что старый подход был неправильным.<!-- .element: class="fragment" data-fragment-index="1" --> * Мы реализовали новый и предлагаем его заинтересованным (под флагом совместимости).<!-- .element: class="fragment" data-fragment-index="2" --> * Через несколько лет он станет основным, если пройдет проверку временем.<!-- .element: class="fragment" data-fragment-index="3" --> --- ## Это так долго... А как же наша репутация? От планомерного, аккуратного, с вниманием к пользователю исправления проблем репутация точно не пострадает.<!-- .element: class="fragment" data-fragment-index="1" --> --- ## Но никто не будет включать флаг совместимости Это знакомый тезис. «Никто не читает документацию и release notes».<!-- .element: class="fragment" data-fragment-index="1" --> Что ж... современному миру *действительно* нужны современные способы коммуникации.<!-- .element: class="fragment" data-fragment-index="2" --> --- ## Например..? Тулкит разработчика. Это не только инструмент для написания и распространения кода, но и способ доставки подходов, практик и рекомендаций до разработчика.<!-- .element: class="fragment" data-fragment-index="1" --> Компиляторы, линтеры и статические анализаторы предупреждают типичные ошибки. Шаблоны приложений распространяют новые практики.<!-- .element: class="fragment" data-fragment-index="2" --> --- ## А флаги совместимости... Могут быть рекомендованы к включению тулкитом разработчика. Например, как часть стандартной команды запуска линтера или тестов.<!-- .element: class="fragment" data-fragment-index="1" --> --- ## Это очень сложно Напротив. Пользователь получает релизы с фичами, но без несовместимых изменений.<!-- .element: class="fragment" data-fragment-index="1" --> Разработчик приложения предупрежден об устаревших подходах и может заранее протестировать приложение с новым подходом.<!-- .element: class="fragment" data-fragment-index="2" --> Все вещи на своих местах.<!-- .element: class="fragment" data-fragment-index="3" --> --- ## <Тут я рисую диаграммку> ```mermaid gantt dateFormat YYYY-MM axisFormat %Y-%m title Жизненный цикл серии релизов (с т. з. пользователя) section Фичсет X.Y Начало разработки :done, 2020-01, 2020-07 Первый релиз (X.Y.0) :milestone, 2020-07 Поддержка :2020-07, 2021-01 Багфикс-релиз (X.Y.1) :milestone, 2020-08, 0d Багфикс-релиз (X.Y.2) :milestone, 2020-09, 0d Багфикс-релиз (X.Y.3) :milestone, 2020-10, 0d Багфикс-релиз (X.Y.4) :milestone, 2020-11, 0d Багфикс-релиз (X.Y.5) :milestone, 2020-12, 0d Багфикс-релиз (X.Y.6) :milestone, 2021-01, 0d section Фичсет X.(Y+1) Начало разработки :done, 2020-07, 2021-02 Первый релиз (X.(Y+1).0) :milestone, 2021-02, 0d Поддержка :2021-02, 2021-07 Багфикс-релиз (X.(Y+1).1) :milestone, 2021-03, 0d Багфикс-релиз (X.(Y+1).2) :milestone, 2021-04, 0d Багфикс-релиз (X.(Y+1).3) :milestone, 2021-05, 0d Багфикс-релиз (X.(Y+1).4) :milestone, 2021-06, 0d Багфикс-релиз (X.(Y+1).5) :milestone, 2021-07, 0d ``` --- ## <И еще одну> ```mermaid gantt dateFormat YYYY-MM axisFormat %Y-%m title Жизненный цикл серии релизов (с пересекающимися фичсетами) section Фичсет X.Y Начало разработки :done, 2020-01, 2020-07 Первый релиз (X.Y.0) :milestone, 2020-07 Поддержка :2020-07, 2021-07 Багфикс-релиз (X.Y.1) :milestone, 2020-09, 0d Багфикс-релиз (X.Y.2) :milestone, 2020-11, 0d Багфикс-релиз (X.Y.3) :milestone, 2021-01, 0d Багфикс-релиз (X.Y.4) :milestone, 2021-03, 0d Багфикс-релиз (X.Y.5) :milestone, 2021-05, 0d Багфикс-релиз (X.Y.6) :milestone, 2021-07, 0d section Фичсет X.(Y+1) Начало разработки :done, 2020-07, 2021-01 Первый релиз (X.(Y+1).0) :milestone, 2021-01, 0d Поддержка :2021-01, 2022-01 Багфикс-релиз (X.(Y+1).1) :milestone, 2021-03, 0d Багфикс-релиз (X.(Y+1).2) :milestone, 2021-05, 0d Багфикс-релиз (X.(Y+1).3) :milestone, 2021-07, 0d Багфикс-релиз (X.(Y+1).4) :milestone, 2021-09, 0d Багфикс-релиз (X.(Y+1).5) :milestone, 2021-11, 0d Багфикс-релиз (X.(Y+1).6) :milestone, 2022-01, 0d ``` --- ## <Ремарка про поддержку миноров> У Python, Go миноры имеют свой небольшой (год-полтора) цикл поддержки, иногда с хвостом из security-поддержки.<!-- .element: class="fragment" data-fragment-index="1" --> Это не поддержка в полном смысле слова (минор не является предметом поддержки), так как проекты в любом случае надо обновлять на новые миноры.<!-- .element: class="fragment" data-fragment-index="2" --> --- Мы можем EOL'ить миноры отложенно, пересекаясь по времени жизни со следующим минором. Но неясно, зачем. * &#x1F44E; Теряем линейность истории релизов.<!-- .element: class="fragment" data-fragment-index="1" --> * &#x1F44E; Создаем ложное впечатление, что минор является предметом поддержки.<!-- .element: class="fragment" data-fragment-index="2" --> * &#x1F44E; Тратим на это силы и время.<!-- .element: class="fragment" data-fragment-index="3" --> * &#x1F44D; Даем возможность подождать подольше с обновлением минора.<!-- .element: class="fragment" data-fragment-index="4" --> --- ## <Ремарка про Ubuntu XX.04 LTS и XX.10> XX.10 в сущности является ознакомительной версией, в prod ее не взять.<!-- .element: class="fragment" data-fragment-index="1" --> У бинарных дистрибутивов есть особая проблема: ABI-совместимость third-party компонентов (пакетов). Это усложняет плавное обновление.<!-- .element: class="fragment" data-fragment-index="2" --> --- ## <Выводы тезисно> * Совместимость — это важно, знать об этом должен каждый.<!-- .element: class="fragment" data-fragment-index="1" --> * Смена поведения возможна, но проходит через свой процесс.<!-- .element: class="fragment" data-fragment-index="2" --> * Поддержка не означает фиксацию набора фич.<!-- .element: class="fragment" data-fragment-index="3" --> * Тулкит разработчика формирует практики разработки.<!-- .element: class="fragment" data-fragment-index="4" --> * С циферками все просто: живем по semver'у.<!-- .element: class="fragment" data-fragment-index="5" --> --- * С циферками все просто: живем по semver'у. * LTS-миноры — странно и неясно, зачем.<!-- .element: class="fragment" data-fragment-index="1" --> * Нет ощущения необходимости поддерживать одновременно два минора.<!-- .element: class="fragment" data-fragment-index="2" --> --- ## И все таки... Ваши вопросы :)<!-- .element: class="fragment" data-fragment-index="1" --> — Александр Туренко, 2022<!-- .element: class="fragment" data-fragment-index="2" style="text-align: right;" --> --- ## Дополнительные материалы * [New release policy (RFC)](https://github.com/tarantool/tarantool/discussions/6182) * [Backward compatibility without tears (RFC)](https://github.com/tarantool/tarantool/discussions/6912) * [Tarantool | endoflife.date](https://endoflife.date/tarantool) * [PEP 602 — Annual Release Cycle for Python](https://peps.python.org/pep-0602/) * [The Go release policy](https://go.dev/doc/devel/release#policy) * [The curl release cycle](https://daniel.haxx.se/blog/2022/08/16/the-curl-release-cycle/)
{"metaMigratedAt":"2023-06-17T12:52:38.088Z","metaMigratedFrom":"Content","title":"Этот релиз точно будет LTS","breaks":true,"contributors":"[{\"id\":\"7ebc1dd7-b122-42d5-b8e8-62dfcf16df97\",\"add\":15004,\"del\":568}]"}
    250 views