Почему параллельный Detox падает раньше, чем заканчивается CPU
Detox честно показывает конкуренцию: «буря» одновременных загрузок Simulator раздувает метаданные APFS быстрее, чем графики CPU. Повторное использование DerivedData между job’ами без фазы promote даёт наполовину записанные деревья: сборка зелёная, а жесты в середине прогона отваливаются. На 1 ТБ набора устройств CoreSimulator, кэши Metro или SwiftPM сталкиваются раньше, чем ожидает руководство.
- Переподписка на сессии: считайте каждый Simulator как ОЗУ плюс framebuffer плюс диск, а не как «один поток на ядро».
- Гонки артефактов: два агента без очереди на общий тёплый кэш ломают инкрементальные сборки.
- Обрыв по диску: жёлтые коридоры для 1 ТБ и 2 ТБ различаются; расширяйте параллелизм только при зелёных водяных знаках.
Сопоставьте этот материал с матрицей Xcode Parallel Testing и бюджетом Simulator для нативных полос xcodebuild, затем вернитесь сюда за спецификой Detox, rsync и приёмкой APFS.
Лимиты параллелизма (бюджет сессий Simulator)
Таблица — контракт между мобильной платформой, CI и FinOps: что реально стоит «ещё одна параллельная полоса» на железе M4.
| Постура | Бюджет параллельных Simulator | Политика DerivedData | WAN / регион | Диск |
|---|---|---|---|---|
| Один регион, всплеск | Старт с двух–четырёх одновременных симуляторов на конфигурациях с 16 ГБ ОЗУ; измеряйте хвостовую задержку перед повышением лимита. | Каталоги в рамках job; не делите один корень DerivedData между параллельными родителями Detox. | Артефакты тяните по LAN; избегайте зависимости тёплого кэша через регион. | 1 ТБ — при еженедельной ротации кэша и жёсткой очистке после merge. |
| Очередь нескольких приложений | Сериализация по идентификатору приложения внутри runner’а; верхняя граница загруженных runtime даже при ожидании в очереди. | После компиляции — promote снимков только для чтения; тесты читают зафиксированное дерево. | Если очередь уходит в другой регион, заложите бюджет задержки в стартовые пробы Detox. | 2 ТБ, если три и более крупных приложения делят один хост. |
| Межрегиональный fan-out | Снижайте параллелизм на узел; чаще добавляйте узлы M4, чем гоните «героический» локальный параллелизм. | Дельты rsync после компиляции в регионе-источнике; потребители проверяют контрольную сумму до boot. | Замерьте RTT и задайте --bwlimit, чтобы передачи не голодали IO Simulator. |
2 ТБ по умолчанию, если WAN-копии и симуляторы делят один том APFS. |
Параметры rsync для производных артефактов
Тёплые кэши должны появляться для потребителя атомарно: стадия в каталог с версией, rsync в архивной семантике, частичные файлы, сжатие — после стабильных ссылок, ограничение полосы на WAN, чтобы загрузка Simulator оставалась в приоритете.
Предпочитайте дельты по времени или контрольным суммам вместо слепых удалений на общих корнях. После копирования — атомарная смена симлинка или переименование каталога одной операцией, чтобы Detox не открыл наполовину заполненное дерево. Узловые шаблоны для такой фермы — в матрице rsync артефактов кластера с примерами flock.
Блокировки и очереди
На каждый путь promote — один писатель: полоса merge-queue, файловая блокировка корня кэша или токен планировщика Nomad. Читателей можно размножать, писателей — только сериализовать, иначе бессмысленно ловить недетерминированные таймауты UI.
Сочетайте очереди CI с хостовым flock на коротких критических участках, где трогают общий DerivedData или наборы CoreSimulator. Эскалацию согласуйте с матрицей Nomad: аффинити и build lock, если на одном Mac mini M4 живут несколько сервисов.
Стратегия масштабирования и расширения
Добавляйте узлы, когда глубина очереди растёт при безопасном водяном знаке диска, а не когда «хочется больше параллелизма» при девяноста процентах заполнения. Сначала снижайте лимиты Simulator на узел, затем шардируйте приложения по хостам, затем бюджетируйте SKU 2 ТБ.
- Еженедельно фиксируйте свободные гигабайты APFS на job,
iowaitи перцентили длительности boot Detox. - Задайте жёлтые и красные водяные знаки по SKU; аварийно прерывайте job, если без утверждённого исключения он пересечёт жёлтую зону.
- Замораживайте новые параллельные полосы, пока хосты в красной зоне; выводите нестабильные машины из ротации.
- Прежде чем расширять WAN fan-out, добавляйте runner’ы M4 в регионе происхождения артефактов.
- После крупного обновления iOS runtime пересчитайте матрицу: кривые хранения CoreSimulator смещаются.
Чек-лист приёмки водяного знака диска 1 ТБ / 2 ТБ
- Preflight по байтам: агент публикует свободные гигабайты APFS; job отменяется ниже жёлтого порога.
- Кап Simulator: активные сессии Detox не превышают подписанную строку матрицы для данного SKU.
- Проверка rsync: контрольные суммы или строгая политика mtime до атомарной смены симлинка.
- Доказательство блокировки: события promote содержат идентификатор блокировки в структурированных логах.
- Политика prune: окна удержания CoreSimulator и DerivedData описаны и автоматизированы.
- Освобождение после сбоя: даже упавшие job’ы освобождают device set и временные деревья в течение часа.
Итог: арендуйте параллельные Mac M4 под реальность Detox
Закупки должны следовать трём кривым: глубина очереди Detox, p95 загрузки Simulator и утилизация APFS. Очередь растёт при зелёном диске — добавляйте параллельные узлы M4 в правильной географии. Диск жёлтеет при «спокойной» очереди — чините кэши и rsync раньше, чем покупать ядра.
Откройте публичные тарифы, загляните в справочный центр по SSH и доступу, затем оформите дополнительные runner’ы, когда чек-лист остаётся зелёным под пиковой нагрузкой Detox.
Масштабируйте полосы Detox на Mac mini M4
Выделенные узлы M4 с томами 1 ТБ или 2 ТБ, явный бюджет Simulator и регионы clustervps рядом с источником артефактов. Связанные материалы: матрица Xcode Parallel Testing, rsync артефактов кластера, Nomad и build lock.