distbuild/

directory
v0.0.0-...-50b27ac Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 3, 2023 License: MIT

README

distbuild

В этом задании вам нужно будет реализовать систему распределённой сборки.

Система сборки получает на вход граф сборки и файлы с исходным кодом. Результатом сборки являются исполняемые файлы и stderr/stdout запущенных процессов.

Граф сборки

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

Джобы в графе сборки запускают произвольные команды. Например, вызывать компилятор, линкер или запускать тесты.

Команды внутри джоба могут читать файлы с файловой системы. Мы будем различать два вида файлов:

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

Команды внутри джоба могут писать результаты своей работы в файлы на диске. Выходные файлы обязаны находиться внутри его выходной директории. Директория с результатом работы джоба называется артефактом.

package build

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
}

Архитектура системы

Наша система будет состоять из трех компонент.

  • Клиент - процесс, запускающий сборку.
  • Воркер - процесс, запускающий команды компиляции и тестирования.
  • Координатор - центральный процесс в системе, общается с клиентами и воркерами. Раздаёт задачи воркерам.

Типичная сборка выглядит так:

  1. Клиент подключается к координатору, посылает ему граф сборки и входные файлы для графа сборки.
  2. Координатор сохраняет граф сборки в памяти и начинает его исполнение.
  3. Воркеры начинают выполнять вершины графа, пересылая друг другу выходные директории джобов.
  4. Результаты работы джобов скачиваются на клиента.

Как решать эту задачу

Задача разбита на шаги. В начале, вам нужно будет реализовать небольшой набор независимых пакетов, которые реализует нужные примитивы. Код в этих пакетах покрыт юниттестами. В каждом пакете находится файл README.md, объясняющий подзадачу.

Рекомендуемый порядок выполнения:

  • distbuild/pkg/build - определение графа сборки. В этом пакете ничего писать не нужно, нужно ознакомиться с существующим кодом.
  • distbuild/pkg/tarstream - передача директории через сокет. В этом пакете ничего писать не нужно, нужно ознакомиться с существующим кодом.
  • distbuild/pkg/api - протокол общения между компонентами.
  • distbuild/pkg/artifact - кеш артефактов и протокол передачи артефактов между воркерами.
  • distbuild/pkg/filecache - кеш файлов и протокол передачи файлов между компонентами.
  • distbuild/pkg/scheduler - планировщик с эвристикой локальности.

После того, как все кубики будут готовы, нужно будет соединить их вместе, реализовав distbuild/pkg/worker, distbuild/pkg/client и distbuild/pkg/dist. Код в этих пакетах нужно отлаживать на интеграционных тестах в distbuild/disttest.

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

Сколько кода нужно написать?
prime@fedora ~/C/s/distbuild (master)> find -iname '*_solution.go' | grep -v scheduler_solution| xargs wc -l
123 ./pkg/api/build_client_solution.go
140 ./pkg/api/build_handler_solution.go
 58 ./pkg/api/heartbeat_client_solution.go
 62 ./pkg/api/heartbeat_handler_solution.go
  5 ./pkg/artifact/cache_solution.go
 44 ./pkg/artifact/client_solution.go
 56 ./pkg/artifact/handler_solution.go
126 ./pkg/client/build_solution.go
121 ./pkg/dist/build_solution.go
122 ./pkg/dist/coordinator_solution.go
 85 ./pkg/filecache/client_solution.go
  5 ./pkg/filecache/filecache_solution.go
101 ./pkg/filecache/handler_solution.go
  5 ./pkg/tarstream/stream_solution.go
 47 ./pkg/worker/download_solution.go
283 ./pkg/worker/job_solution.go
 25 ./pkg/worker/state_solution.go
113 ./pkg/worker/worker_solution.go
1521 total

Directories

Path Synopsis
pkg
api
api/mock
Package mock is a generated GoMock package.
Package mock is a generated GoMock package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL