[devel] IХ. Алгоритмы работы сборочницы. O commit. ч.1

Igor Vlasenko vlasenko на imath.kiev.ua
Сб Мар 23 13:17:19 MSK 2019


Уважаемые господа!

Продолжаю цикл писем, посвященный предложениям по улучшению
нашей сборочницы.

Письма I - VIII можно посмотреть здесь:
  https://www.altlinux.org/Girar/Parallel

Письмо IХ. Алгоритмы работы сборочницы. O task merge (commit). ч.1
-------------------------------------------------

task merge - это операция, которая получает из репозитория R_n
и собранного таска B новый репозиторий R_{n+1}.

R_n + B -> R_{n+1}

На этапе task merge в параллельной сборочнице у нас
возникает проблема, которой в последовательной сборочнице не было.
Таск B был, вообще говоря, собран не с текущим репозиторием R,
а с каким-то более старым репозиторием R_k,  k <=n.
Таск B прошел проверки целостности для R_k,
но у нас теперь R_n и B может иметь, к примеру, unmets.

Что наша сборочница должна делать на этапе task merge?
Она должна повторить проверки целостности для B, но
уже на R_n. Если B проходит проверку, делаем commit
и получаем новый репозиторий R_{n+1}.
Иначе возвращаем B в очередь build, на пересборку с R_{n+}.

Что наша сборочница делает, но делать этого не должна,
против чего я выступаю?

Сборочница просто берет и принудительно пересобирает B на R_n.
Да, там есть оптимизация - если сборочное окружение пакета
не изменилось, то его пересборка очевидно избыточна,
и тогда B коммитится без пересборки, что иногда ускоряет
сборочницу.
Однако по сути для не test-only пакетов это та же последовательная
сборочница. Привязка commit к повторной пересборке
является в ней узким местом.

И не просто узким в процентах, а узким местом в абсолютных
величинах, т.е. есть определенный порог, число пакетов,
которые такая сборочница способна обработать в сутки.

По достижении этого порога сборочница просто захлебнется.
Но сначала резко увеличится среднее время ожидания
до попадания пакета в сизиф, пакеты начнут стоять в очередь
на commit часами, потом сутками,
появятся AWAITING 1.12, AWAITING 1.18 ...
начнется грызня, обвинения, что кто-то заливает слишком много пакетов,
придирки, что пакет залит по недостаточно важной причине,
рулеж очередью пакетов вручную,
попытки усложнить майнтайнерам доступ к commit
(сейчас вот появилась опция --commit, однако ее
легко заскриптовать; скоро против этого, боюсь, в сборочницу
и ssh капчу начнут встраивать :)

Если не прекратить это безобразие, и не исправить проблему
в корне, т.е. не распрямить кривизну в алгоритмах,
то мы скоро придем к тому, что на доступ к сборочнице
талоны будут выдавать.

Теперь я хотел бы пояснить, что я понимаю под
кривизной в алгоритмах.

Сама по себе пересборка - вещь достаточно полезная,
если ее применять правильно.

Дмитрий и Алексей писали о ее полезности:
at@:
 unmet - это влияние, которое удалось формализовать. Это счастливый
 случай, когда в черный ящик удается воткнуть предметную проверку. Но
 все влияния формализовать очень тяжело. Например, неизвестно даже,
 соберется ли пакет с новой библиотекой, и достаточно ли новая
 библиотека совместима со старой, чтобы пытаться протащить в
 репозиторий таск, собранный со старой библиотекой.

 Выход мне кажется концептуальный только один: строгая сериализация
 транзакций. Каждый таск начинает собираться на свежем состоянии
 репозитория и порождает следующее состояние.

ldv@:
 Уточню: я считаю очевидным, что если сборочная среда пакета в задании
 изменилась, то этот пакет подлежит пересборке.  Если пакет в результате
 пересборки изменился, то все касающиеся его тесты подлежат перепроверке.

 Более того, я считаю очевидным, что если свежесобранный пакет входит в
 сборочную среду других пакетов, то все они должны быть незамедлительно
 пересобраны и перепроверены.  К сожалению, это у нас ещё не реализовано.

Я с этим, в принципе, согласен, если
1) речь идет о корректно реализованной пересборке и
2) мы потянем требуемые для этого ресурсы.

К примеру:
Пришла в Сизиф новая libpng, и пересобрали все "затронутые" пакеты.
Пришел в Сизиф новый gcc, и пересобрали все пакеты, собиравшиеся
старым gcc.

Здесь есть подводные грабли, которые нужно обходить очень деликатно.
Первое, это циклы зависимостей.
Пересобрали foo, затронут bar. Пересобрали bar, затронут foo.
Нужно не пересобирать цикл бесконечно, а остановиться
после 1-2 пересборок.
Для этого нужна хоть простая, но БД, где будет храниться состояние.
Заодно, можно оптимизировать пересборку, откладывать ее подольше,
чтобы очистить одной пересборкой сразу множество поводов.

Второе, это ресурсы. Обновление пакетов в Сизифе может оказаться
слишком дорогостоящим, ведь два пакета до и после пересборки бинарно
разные, их не схардлинкуешь и архив Сизифа начнет резко дуться.
Новый месяц - новый винт, раз в квартал к этим винтам
надо докупить серверок, через пару лет докупить СХОДик,
чтобы было куда сервера ставить. Потянем такое?

Чтобы таких вещей не было, пересборка должна быть умной.
К примеру, сколько пакет с фотообоями на рабочий стол не пересобирай,
ни резкость на картинке не улучшится, ни яркость не добавится.

Или скриптовые модули, к примеру, rubygems.
Там основная часть работы rpm
состоит из вызова tar -x ; /usr/bin/install; tar -c.
Имеет ли смысл их пересобирать __ в Сизиф __ ?

Просто пересобирать их в сторонке, в Beehive, конечно, стоит.
Слом сборки, изменения в requires ...
Все это важные симптомы, с которыми надо разбираться.

Но в остальных случаях для таких пакетов пересборка будет будет
очевидно бессмысленной.
Или java. Там есть компиляция, но это язык для кодеров за еду,
и с защитой от кодеров за еду. Там нет макросов и 
проблемы там устроены так, что пересборкой не лечатся.

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

Такое, да, было бы полезно.
Но что мы видим у нас? Делает ли сборочница такую пересборку?
Очевидно, нет.

К примеру, приходит в Сизиф новая libfoo. Свежесобранный
пакет входит в сборочную среду сотен других пакетов.
unmets нет, но мы боимся, вдруг чего бы не вышло.
Поэтому по логике, для решения постулируемых  задач
пересборки все затронутые пакеты должны быть незамедлительно
пересобраны и перепроверены.

Что делает сборочница? Она хватает и пересобирает случайную
парочку пакетов из очереди, которым не повезло оказаться в
очереди именно в этот момент. Остальные сотни других пакетов
в Сизифе так и остаются собранными со старой libfoo.

Не абсурд ли это?

пересборка у нас сейчас реализована по классическому
алгоритму: шумиха, неразбериха, поиск
виновных, наказание невиновных, награждение непричастных. 

К примеру, по такой логике такие пакеты, как
янв  4 2005 xlhtml-0.5.1-alt2.src.rpm
десятилетиями каждый день получают новые поводы, чтобы
пересобраться, но почему-то до сих пор не пересобраны.

Чем 2 пакета, собранные за 5 минут до прихода в Сизиф
новой libfoo, хуже, чем 200 пакетов, собранных еще раньше?
Ничем не хуже. Даже лучше с точки зрения необходимости
пересборки, так как собраны на более свежем Сизифе.

Их пересборка -- это логическая ошибка, что-то вроде
известной "ошибки выживших".


-- 

I V


Подробная информация о списке рассылки Devel