# Локальная сборка и кэширование

Утилите ```ya``` для сборки проектов, кроме рабочей копии репозитория, требуется временное дисковое хранилище для вспомогательных и промежуточных файлов, а также
место для результатов сборки. Кэширование конфигурации сборки (```ymake``` кэши) описаны в другом месте.

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

Ниже описаны настройки удаления файлов для разных типов файлов.

Параметры могут быть указаны либо локально на машине в файле ```~/.ya/ya.conf```, либо в репозитории в файле ```junk/<login>/ya.conf```.  Рекомендуется
использовать файл в ```junk```, чтобы всегда иметь иметь настройки, совместимые с ```ya```.

## Результаты сборки { #local-results }
Результаты сборки могут быть сложены на постоянное хранение в место, указанное с помощью опции ```-o/--output <path>```. Система сборки никак не отслеживает
файлы в директории ```<path>```, и удалять их надо вручную.

На Linux/MacOS, если не указана опция ```--no-src-links```, результаты будут сложены во временное хранилище, кэш результатов. В этом случае файлы и
директории из кэша результатов доступны по символическим ссылкам из рабочей копии репозитория.

Удаление из кэша результатов происходит по истечении срока жизни, которое по умолчанию равно неделе, а изменить срок жизни файлов можно параметром ```symlinks_ttl```.

## Вспомогательные файлы сборки { #local-tool-cache }
К вспомогательным файлам сборки относятся компиляторы, SDK, эмуляторы и другие инструменты, которые сами не строятся, но нужны во время запуска ```ya``` для
построения, запуска тестов и т.п. Такие файлы хранятся в кэше инструментов.

Автоматическое удаление настроено на Linux/MacOS.

Политика удаления этих файлов - LRU, при ограничении на объем потребляемого дискового пространства. Ограничение по умолчанию может быть переопределено
параметром ```tools_cache_size```.

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

Если инструменты запускаются, используя прямые пути, полученные, например, с помощью ```ya tool cc --print-path```, то такие инструменты не будут чиститься
автоматически, так как мы не можем контролировать такой сценарий. Такие инструменты автоматически будут очищены в обычном порядке после запуска ```ya gc
cache```

## Временные файлы сборки { #local-ya-cache }
Временные файлы сборки бывают 3-х типов.
1. Временные файлы, созданные с помощью функций, производных от ```mktemp/mkdtemp``` и т.п. Эти файлы создаются во временной директории,
   которая полностью удаляется в конце работы ```ya```.
2. Временные файлы, которые могут быть использованы в других сборках. К ним относятся промежуточные файлы построения, которые описаны в сборке явно
   через ```ya.make``` файлы. Общий размер диска, отведенного для таких файлов, можно ограничить с помощью ```cache_size```. Политика удаления - LRU.
   Файлы, скачанные из [распределенного кэша](yt_store.md), тоже относятся к этому типу.
3. Временные файлы, используемые в текущей сборке, или директории построения. В большинстве случаев эти файлы являются ссылками на файлы
   из п.2. Такие файлы отнесены в отдельную категорию по нескольким причинам. Во-первых, некоторые промежуточные файлы явно запрещено
   использовать в других сборках, во-вторых, режим сборки с ключом ```--rebuild``` подразумевает использование исключительно файлов из
   текущего построения, в-третьих ограничение по размеру кэша может быть слишком маленьким для текущего построения.
   Файлы из этой категории по умолчанию либо удаляются во время текущей сборки, либо во время следующей сборки.

Мгновенное потребление диска за счет файлов из пп. 1 и 3 ограничить заранее нельзя.

Файлы из п.2 хранятся в локальном кэше сборки.

## Настройки
Три основные настройки автоматической очистки файлов:
1. ```cache_size``` ограничение на размер [локального кэша](#local-ya-cache)
2. ```tools_cache_size``` ограничение на размер [кэша инструментов](#local-tool-cache).
3. ```symlinks_ttl``` ограничение на время жизни [результатов сборки](#local-results), которые кэшируются ```ya```.  Время жизни отсчитывается со времени создания.

Автоматическое удаление можно отключить, задав большие значения для этих параметров, а удаление директорий построения отключается с помощью опции ```--keep-temps```.

### Пример настроек в ya.conf
```
tools_cache_size = "6GiB"
symlinks_ttl = "1h"
cache_size = "80GiB"
```
Без кавычек можно задавать размер в байтах или время в секундах, например, ```symlinks_ttl = 3600```

## Ручная очистка { #local-manual-gc }
Кроме автоматической очистки кэшей, можно явно почистить диск с помощью команды ```ya gc cache```. Вместе с очисткой делаются дополнительные проверки на ошибки.

Команда полностью удаляет
- все вспомогательные файлы, кроме тех, которые чистятся автоматически
- все временные файлы, кроме [локального кэша](#local-ya-cache).

Файлы локального кэша сборки удаляются в соответствии с одним из фильтров:
```
--object-size-limit=OBJECT_SIZE_LIMIT
    Strip build cache from large objects (in MiB if not set explicitly)
--age-limit=AGE_LIMIT
    Strip build cache from old objects (in hours if not set explicitly)
```
Если не задан фильтр, то будет сделана очистка в соответствии с настройкой ```cache_size```


## Параллельные запуски сборок { #local-parallel-conflicts }
Правки в рабочей копии репозитория запрещены во время сборки, иначе возможно отравление кэшей из-за разнесенного по времени подсчета uid'ов и генерации
файлов для этого уида. Простой перезапуск в этом случае не поможет - требуется полная пересборка с опцией ```--rebuild```
или даже полное удаление кэшей, - так как система сборки использует uid'ы, а не mtime.

Параллельные запуски процессов сборки должны гарантировать отсутствие конфликтов при записи результатов. Конфликты при обращении к временным и вспомогательным
файлам обрабатываются ```ya make``` самостоятельно.

## Статистики, анализ локальной сборки { #local-stats }
Запуск ```ya make``` с опцией ```--stat``` выдает информацию о построении без учёта конфигурирования, пакетирования и т.п.
Параметр ```print_statistics = true``` конфигурационного файла задаёт эту опцию для всех сборок с помощью ```ya make/package``` и т.п.

Пояснение будет дано на примере
```
Info: Node count in the dependency graph is 120340.
Info: Dependency count in the graph is 175273.
Cache hit ratio is 98.79% (85973 of 87024)
# Из графа построения были исполнены только 87024 - 85973 = 1051 узлов. Результаты остальных узлов пришли из локального кэша или распределенного кэша.
# 85973 меньше 120340, так как в число 120340 входят индивидуальные скачивания тулов, задачи записи в кэш и т.п. См. prepare ниже, а так же статистики для кэшей.

```

```
Disk usage for tools/sdk 2.18 GiB
# В кэше инструментов было использованы около 2.18 GiB дискового пространства.
# Значение зависит от того, сколько команд было исполнено, например, если в кэшах были все нужные построения, то компилятор не попадёт в эту статистику.
Additional disk space consumed for build cache 20.29 GiB
# В локальный кэш сборки были дополнительно положены файлы, общий размер которых 20.29 GiB. Учитываются локально исполненные команды и данные из распределенного кэша, продублированные локально.
```

```
Critical path:
[4779 ms] [CC] [eoYv2szE-ix4fS2BbKYhTg]: $(SOURCE_ROOT)/contrib/restricted/boost/libs/python/src/object/inheritance.cpp [started: 0 (1594179882553), finished: 4779 (1594179887332)]
[ 107 ms] [AR] [c1NkJ25BNAn20mFd7FO2hQ]: $(BUILD_ROOT)/contrib/restricted/boost/libs/python/libboost-libs-python.a{, .mf} [started: 4800 (1594179887353), finished: 4907 (1594179887460)]
[5851 ms] [LD] [IDUy5TtSrxw_Ek14XJY6Jw]: $(BUILD_ROOT)/sandbox/tasks/tasks{, .mf} [started: 28452 (1594179911005), finished: 34303 (1594179916856)]
# Критический путь в графе построения (из 87024 - 85973 узлов).
# Чтение из кэшей не учитываются в этом графе.
```

```
Time from start: 336187 ms, time elapsed by graph 10737 ms, time diff 325450 ms.
# Сравнение реального времени исполнения с оценкой времени исполнения исходя из критического пути.
# Разница складывается из-за задержек в очереди на исполнение (недостаток свободных потоков), задержек доставки файлов из кэшей и других накладных расходов
```

```
The longest 10 tasks:
[9422450 ms] [prepare:$(yt-store-get)] local [count: 16164, cps: 1.72, ave time 582.93 msec, failures 210]
# Статистика скачиваний из yt-кэша и последующей распаковки. Скачали 2571 результатов узлов из тех 7936, которые не были перестроены.
# Скачивание параллельное, а 1104 сек характеризует последовательное скачивание, поэтому нужно делать поправку на количество потоков сборки.
# cps (calls-per-seccond) тоже не учитывает параллельное исполнение (в идеальном параллельном исполнении число надо умножать на число потоков --yt-store-threads).
[  84795 ms] [prepare:$(AC-put)] local [count: 17005, cps: 200.54, ave time 4.99 msec]
# Статистика записи в локальный кэш. Запись идет не более, чем в 2 потока.
[  60023 ms] [prepare:FromDistCache(aVv9FCkkaMHM4U6FMXEb8g$(BUILD_ROOT)/sandbox/projects/media/kp-front-nginx/177ad19c87bfc27c45d0778ae3.cpp.o)] local [started: 1594179698517, finished: 1594179758540]
# Индивидуальное скачивание из yt-кэша.
...

```

```
Total time by type:
[prepare:get from dist cache] - 9602388 ms.
# Суммарное время на скачивание из yt-кэша.
[prepare:yt-store] - 9432840 ms.
# Суммарное время на работу с yt-кэшем. Статистика, собранная в кэше без привязки к отдельным задачам графа исполнения.
[CC] - 532439 ms
[prepare:AC] - 116367 ms.
# Это суммарное время, затраченное на работу с локальным кэшем, чтения, записи, и т.п. Результаты большинства узлов графа построения складывается в локальный кэш.
# Можно использовать для оценки порядка накладных расходов на организацию локального исполнения. Для каждого файла, сложенного в кэш, насчитывается хэш, так что расходы небольшие, но нетривиальные.
# Статистика, собранная в кэше без привязки к отдельным задачам графа исполнения.
[prepare:put into local cache, clean build dir] - 109057 ms.
# Запись в локальный кэш с удалениями рабочих директорий.
[LD] - 18172 ms.
[AR] - 15739 ms.
[PR] - 1487 ms.
[PY] - 1435 ms.
[AS] - 813 ms.
[prepare:clean] - 676 ms.
[prepare:get from local cache] - 561 ms.
[BI] - 192 ms.
[JS] - 83 ms.
[PB] - 40 ms.
[prepare:tools] - 38 ms.
# Видно, что никакие инструменты не скачивались из sandbox'а, а были извлечены из кэша инструментов.

Statistics overhead 4250 ms
# Время, потраченное на подсчёт статистик.
```
