diff --git a/distbuild/README.md b/distbuild/README.md new file mode 100644 index 0000000..b5105f9 --- /dev/null +++ b/distbuild/README.md @@ -0,0 +1,122 @@ +# distbuild + +В этом задании вам нужно будет реализовать систему распределённой сборки. + +Система сборки получает на вход граф сборки и файлы с исходным кодом. Результатом сборки +являются исполняемые файлы и stderr/stdout запущенных процессов. + +## Граф сборки + +Граф сборки состоит из джобов. Каждый джоб описывает команды, которые нужно запустить на одной машине, +вместе со всеми входными файлами, которые нужны этим командам для работы. + +Джобы в графе сборки запускают произвольные команды. Например, вызывать компилятор, линкер или +запускать тесты. + +Команды внутри джоба могут читать файлы с файловой системы. Мы будем различать два вида файлов: + - Файлы с исходным кодом с машины пользователя. + - Файлы, которые породили другие джобы. + +Команды внутри джоба могут писать результаты своей работы в файлы на диске. Выходные файлы +обязаны находиться внутри `OUTPUT_DIR` директории. + +```go +package graph + +import "crypto/sha1" + +// ID задаёт уникальный идентификатор джоба. +// +// Мы будем использовать sha1 хеш, поэтому ID будет занимать 20 байт. +type ID [sha1.Size]byte + +// Job описывает одну вершину графа сборки. +type Job struct { + // ID задаёт уникальный идентификатор джоба. + // + // ID вычисляется как хеш от всех входных файлов, команд запуска и хешей зависимых джобов. + // + // Выход джоба целиком опеределяется его ID. Это важное свойство позволяет кешировать + // результаты сборки. + ID ID + + // Name задаёт человекочитаемое имя джоба. + // + // Например: + // build gitlab.com/slon/disbuild/pkg/b + // vet gitlab.com/slon/disbuild/pkg/a + // test gitlab.com/slon/disbuild/pkg/test + Name string + + // Inputs задаёт список файлов из директории с исходным кодом, + // которые нужны для работы этого джоба. + // + // В типичном случае, тут будут перечислены все .go файлы одного пакета. + Inputs []string + + // Deps задаёт список джобов, выходы которых нужны для работы этого джоба. + Deps []ID + + // Cmds описывает список команд, которые нужно выполнить в рамках этого джоба. + Cmds []Cmd +} + +// Cmd описывает одну команду сборки. +// +// Есть несколько видов команд. Все виды команд описываются одной структурой. +// Реальный тип определяется тем, какие поля структуры заполнены. +// +// exec - выполняет произвольную команду +// cat - записывает строку в файл +// +// Все строки в описании команды могут содержать в себе на переменные. Перед выполнением +// реальной команды, переменные заменяются на их реальные значения. +// +// {{OUTPUT_DIR}} - абсолютный путь до выходной директории джоба. +// {{SOURCE_DIR}} - абсолютный путь до директории с исходными файлами. +// {{DEP:f374b81d81f641c8c3d5d5468081ef83b2c7dae9}} - абсолютный путь до директории, +// содержащей выход джоба с id f374b81d81f641c8c3d5d5468081ef83b2c7dae9. +type Cmd struct { + // Exec описывает команду, которую нужно выполнить. + Exec []string + + // Environ описывает переменные окружения, которые необходимы для работы команды из Exec. + Environ []string + + // WorkingDirectory задаёт рабочую директорию для команды из Exec. + WorkingDirectory string + + // CatTemplate задаёт шаблон строки, которую нужно записать в файл. + CatTemplate string + + // CatOutput задаёт выходной файл для команды типа cat. + CatOutput string +} +``` + +## Архитектура системы + +Наша система будет состоять из трех компонент. + * Клиент - процесс запускающий сборку. + * Воркер - процесс запускающий команды компиляции и тестирования. + * Координатор - центральный процесс в системе, общается с клиентами и воркерами. Раздаёт задачи + воркерам. + +Типичная сборка выглядит так: +1. Клиент подключается к координатору, посылает ему граф сборки и входные файлы для графа сборки. +2. Кооринатор сохраняет граф сборки в памяти и начинает его исполнение. +3. Воркеры начинают выполнять вершины графа, пересылая друг другу выходные директории джобов. +4. Результаты работы джобов скачиваются на клиента. + +## Протокол: Клиент <-> Координатор + +## Протокол: Координатор <-> Воркер + +## Кеширование + +### Кеш исходного кода + +### Кеш артефактов + +## Тестирование +