October 18th, 2016

404

О теоретической боли зависимостей

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

Остаётся написать небольшой кусочек, и тут программист обнаруживает, что ему нужен Особо Модный Декоратор. Допустим, timeout_decorator. Который есть в pip'е, но которого нет в репозиториях. Допустим, что экивалента нет (я не проверял, это просто гипотетическое), или то, что есть, катастрофически отстаёт.

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

Какие варианты мы имеем?

1. Написать в dependencies и молчать в тряпочку. Билд фейлится - боль девопсов. Ещё хуже, билд не фейлится, а пакет не ставится. Ещё хуже, пакет ставится, но ломается на запуске со словами "нет такого модуля".
2. Написать в dependencies и попросить devops'ов что-то с этим сделать. Если devops добросовестный, то он пойдёт и запакетирует сборку этой библиотеки, а если надо, то и её зависимости. После этого нужно будет обновить билд-скрипт/задачу, чтобы они цепляли кастомный миррор с этой зависимостью, плюс у на появится хронологическая зависимость при бутстрапе: сначала собрать и попушить в миррор депенденсы, а потом уже можно пробововать запускать на сборку приложение.
3. Молча положить в libs/ и импортировать как libs/timeout_decorator.
4. Положить временно туда же и написать devops'ам, мол, разберитесь.
5. Забить на пакетирование и сказать "выкатывайте на продакшен pip'ом".
6. Пойти и написать своё такое же в составе приложения.

И ни один из этих вариантов не ведёт к увеличению количества счастья на планете.

Вариант с пакетированием - увеличение сложности скрипта, многоуровневые зависимости в системе сборки пакетов, затраты времени devops'ов, необходимость мейнтейнить пакеты.
Вариант с lib/ - блобизация всего на свете, проблемы с выниманием его когда эта либа появится в дистрибьютивах, неявное отсутствие maintanance чужого кода.
Вариант с pip-install'ом - перенос всех проблем с совместимостью и доступностью (а так же воспроизводимостью) на runtime, то есть мультипликация несчастья в разах и часах.
Переписать самим - увеличение размера приложения, потраченное время программистов, усложнение кода, преступление класса NIH, проблема maintanance остаётся, но растворяется в за остальным кодом.

Наименее разрушительным вариантом я вижу всё-таки вариант с отдельным пакетированием. Второй по ужасности - lib/. Но и тот и тот - слишком дорого.

А слишком дорого оно потому, что мы привыкли к низкой стоимости добавления кода. Добавить к нашему приложению 20 Мб исходных текстов? Да как нефиг делать - apt-get install foobar-server foobar-client, поехали. И получается, что у нас есть uncanny valley между адекватный код в составе дистрибутива - и вне его. Не существует мягкого градиента, оно либо так, либо нет.