# Этот релиз точно будет 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 и т. д.<!-- .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'ить миноры отложенно, пересекаясь по времени жизни со следующим минором. Но неясно, зачем.
* 👎 Теряем линейность истории релизов.<!-- .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" -->
---
## <Ремарка про 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}]"}