FAQ: когда строгая сериализация лучше ограниченного параллелизма?
Строгая сериализация означает: не более одной «тяжёлой» сборки одновременно касается изменяемого общего состояния — один архив, одна волна интеграционных тестов с Simulator, одна запись в общий кэш зависимостей. Задержка растёт под нагрузкой, зато исчезают тонкие повреждения данных и «плавающие» падения.
Ограниченный параллелизм (например две лёгкие job) работает только при раздельных рабочих деревьях, непересекающихся путях артефактов и запасе по RAM и диску. Если две задачи всё ещё делят один каталог CocoaPods, глобальный npm-кэш без разделения имён или одну оконную сессию Xcode по VNC, выигрыш по времени превращается в генератор инцидентов.
Практическое правило: начните с сериализации для тяжёлых шагов + общего кэша; повышайте параллелизм только когда метрики показывают запас (CPU устойчиво примерно ниже 75%, свободной RAM остаётся порядка 8–16 ГБ после macOS) и у каждой job свой изолированный workspace. Политику полос и меток оркестратора согласуйте с очередью до того, как увеличивать число одновременных job в YAML.
FAQ: как использовать flock на общей сборочной машине?
flock задаёт рекомендательные файловые блокировки: согласующиеся процессы не мешают друг другу; это не песочница от злонамеренных задач. На общем Mac заводите один lock-файл на домен ресурса — например /var/lib/build-locks/pod-shared.lock для общего кэша Pod или /var/lib/build-locks/simulator-ui.lock, если допускается только один поток GUI-тестов.
- Быстрый отказ:
flock -n /path/to.lock -- критическая_команда— если замок занят, сразу выходим; удобно, когда CI может переназначить job на другой узел. - Ожидание с потолком:
flock -w 180 /path/to.lock -- критическая_команда— ждём до 180 секунд для коротких секций вроде обновления общего кэша. - Узкая критическая секция: оборачивайте только мутации (install, запись кэша, переиндексация), а не сорокаминутную компиляцию целиком, если toolchain это позволяет.
Shell-уровень flock дополняйте политикой каталогов и синхронизации артефактов между хостами — см. матрицу rsync, NFS и кэш артефактов, чтобы семантика блокировок совпадала с тем, как вы копируете и публикуете билды.
FAQ: глубина очереди, таймаут job и ожидание flock
Потолок глубины очереди останавливает тихое голодание: если пятьдесят пайплайнов могут встать в ожидание без верхней границы, разработчики решат, что «CI сломан», хотя Mac просто перегружен. Разумная отправная точка — до ~20 ожидающих задач глобально или отдельно по полосам (release против PR); дальше — отказ с явным текстом «пул перегружен — повторите позже или смените метку».
Таймауты job должны отражать максимально разумную длительность сборки, а не рекорд ночного эксперимента. Ориентиры: линт и небольшие юниты 15–25 минут; полная компиляция и тесты 35–60 минут; архив и загрузка в стиле App Store 45–90 минут. Подстраивайте по p95 длительности плюс запас и ужесточайте, если задачи утекают по ресурсам.
Таймаут ожидания замка (flock -w) должен быть короче таймаута job: если за несколько минут не удаётся взять блокировку общего кэша, вероятна зависшая job или слишком широкая критическая секция — это сигнал к алерту, а не к ожиданию до утра.
FAQ: стабильность узла, зависшие замки и конфликты
Стабильность общего Mac — это наблюдаемая очередь и ограниченные побочные эффекты. Следите за медианой и p95 времени ожидания в очереди, p95 ожидания блокировки, свободным местом на системном томе и свопом. Алерты: медиана ожидания стабильно выше ~15 минут в рабочие дни; диск ниже ~15% или ~40 ГБ (что больше).
При конфликтах — дублирующиеся клоны, гонки загрузки Simulator, диалоги подписи — относитесь к ним как к долгу дизайна. Краткосрочно: отменить зависшую job, убедиться, что живой процесс не держит lock, зафиксировать runner id и путь lock в журнале, при «заклинивании» оркестратора перезапустить только сервис воркера. Долгосрочно: разделить интерактив и CI, выделить узел под UI-тесты или добавить вторую сборочную машину раньше, чем снова поднимать параллелизм.
Сетевой транспорт и сеансы SSH тоже влияют на картину: согласуйте keepalive и ожидания переподключения с внутренним SLA, чтобы флаки сети не маскировались под contention блокировок. В разделе блога есть отдельные материалы по стабильности и задержкам — их удобно добавить в тот же runbook.
Таблица исполняемых параметров (копирование в runbook)
| Параметр | Стартовое значение | Заметки |
|---|---|---|
| Потолок тяжёлых серийных сборок | 1 активная на общий кэш / GUI Simulator | Повышайте только при изолированных workspace и раздельных доменах lock |
| Параллелизм лёгких job | до 2 при CPU ~<75%, свободной RAM >~8 ГБ | Останавливайтесь при свопе и скачках задержки диска |
| Макс. глубина очереди (pending) | ~20 глобально или по полосе | Отказ с явным текстом и подсказкой retry |
flock -n |
Неблокирующий режим на занятом ресурсе | Когда другой узел может принять job |
flock -w (сек.) |
120–300 (deps/кэш), 30–60 (короткие секции) | Калибровка по измеренному p95 ожидания |
| Таймаут job (лёгкий / стандарт / архив) | 15–25 / 35–60 / 45–90 мин | Корректировать по p95 репозитория + запас |
| Алерт по медиане ожидания | > 15 мин устойчиво | Масштабирование или разделение полос |
Чеклист эксплуатации: очереди, замки и конфликты
- Именуйте lock по ресурсам, а не по командам: один замок на домен Pod/npm/Simulator.
- Публикуйте потолки очереди во внутренней документации и в сообщениях об ошибках CI.
- Ограничивайте ожидание flock значением короче таймаута job; алерт при повторяющихся таймаутах замка.
- Проверяйте зависшие job перед удалением lock-файлов; логируйте runner id, коммит и путь lock.
- Еженедельный обзор: тренд глубины очереди, свободный диск, рост DerivedData, нужно ли дробить серийные полосы.
Итог и следующие шаги
Общие удалённые Mac вознаграждают скучную координацию: явные серийные полосы там, где состояние общее; flock вокруг реальных критических секций; очередь с громким отказом при переполнении; таймауты, совпадающие с измеренными длительностями. Ограниченный параллелизм — оптимизация, которую вы зарабатываете изоляцией и метриками, а не настройка по умолчанию, когда пять репозиториев делят один кэш.
Когда будете переносить эти параметры на выделенное железо, откройте главную Meshmac для сравнения тарифов, страницу покупки и планов без входа для ёмкости команды и центр помощи по SSH, VNC и базовой безопасности. Полный список материалов — в разделе блога.
Арендуйте удалённый Mac под серийные полосы и предсказуемый CI
После копирования таблицы параметров в runbook подберите ёмкость так, чтобы медиана ожидания оставалась ниже линии алерта. Тарифы и узлы — на главной; оформление без входа — страница покупки. Справка: центр помощи, блог.