Перейти к содержимому

Архитектура

Для опытных

Узнайте, где лежит код и какие правила действуют, прежде чем менять что-то крупное.

HolyArrs — это одна программа на Go со встроенным веб-приложением. Она отдаёт веб-приложение и JSON API на порту 6262 и хранит данные в 2 файлах SQLite в папке конфигурации. Наружу она обращается к загрузчикам, Источникам (через Jackett или Prowlarr), медиасерверам, каналам оповещений и серверу метаданных HolyArrs.

Проследим за одним запросом. Кто-то запрашивает фильм в Обзоре.

  1. requests записывает запрос.
  2. После одобрения movies просит у sources релизы.
  3. Правила отбора в mediafiles выставляют им баллы.
  4. downloads отправляет лучший релиз в загрузчик.
  5. Когда загрузка завершается, mediafiles импортирует файл.
  6. mediaservers и alerts получают сообщение об этом.
app/backend/cmd/holyarrs/ main.go starts the program; wiring.go builds the modules and joins them
app/backend/internal/<module>/ one flat folder per module
app/backend/internal/core/ plumbing every module may use
app/backend/tools/ dev-only programs
app/frontend/ the SvelteKit web app; embed.go bundles its build
app/frontend/src/routes/<page>/ thin pages that combine module parts
app/frontend/src/lib/<module>/ each module's web code
app/frontend/src/lib/ui/ parts used by 2 or more modules, and nothing else
app/frontend/src/lib/core/ server client, app state, helpers
app/tests/ end-to-end tests (Playwright)
deploy/ the Dockerfile and release scripts
docs/ guides and these pages

go.mod лежит в корне репозитория, потому что go:embed не может дотянуться до родительской папки.

Что вы хотите изменить Где смотреть
Как выбирается релиз internal/mediafiles
Клиент загрузчика internal/downloads, контрактные тесты в internal/downloads/conformance_test.go
Канал оповещений internal/alerts
Вход, пользователи, ключи API internal/accounts
Мастер первого запуска internal/setup, app/frontend/src/routes/welcome
Импорт готового файла (распаковка, теги, сопоставление) internal/importer
Папки Медиатеки, принятие и переименование internal/library
Как выбираются и упорядочиваются ряды и полки internal/suggest
Какие Части приложения включены internal/core/parts
Адрес страницы app/frontend/src/routes/
Миграция internal/core/database/migrations/
Docker-образ deploy/Dockerfile

Проверки в app/backend/tools/structurecheck роняют сборку, если какое-то правило нарушено. Запустите их строкой из раздела Тестирование.

  • Порядок слоёв. Модуль импортирует только модули с более низкого слоя, и только их корневой пакет. Модули одного слоя никогда не импортируют друг друга.
  • Вызов наверх. Когда нижнему модулю нужно что-то от верхнего, верхний передаёт вниз простые данные, либо нижний объявляет небольшой интерфейс, который заполняет wiring.go.
  • SQL остаётся дома. SQL есть только в собственных файлах store*.go модуля, и только для его собственных таблиц. Чтобы прочитать строки другого модуля, вызовите его сервис.
  • Общие таблицы принадлежат core. К settings, schedules, secrets, jobs и events обращайтесь через помощники core.
  • Один выход наружу. Каждый внешний вызов идёт через core/outbound.
  • Придержанные функции регистрируют переключатель в core/startup. Пока он выключен, маршрута нет, а страница прячет функцию.
  • Никаких пакетов «для всего подряд». Никаких util, common, shared или helpers.

Порядок слоёв описан в разделе Модули.

Внутри модуля

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

Файл Что в нём
routes.go Маршруты API, у каждого указано нужное право
service.go и файлы по темам Логика, которую вызывают другие модули
store.go, store_<topic>.go Весь SQL для собственных таблиц модуля
types.go Записи модуля

На стороне веба в lib/<module>/ лежат index.ts (то, чем могут пользоваться другие модули), его Svelte-части и их тесты, а api.ts и state.svelte.ts — только когда у модуля есть свои вызовы или состояние.

Пакеты core

Core — это обвязка. В нём нет правил продукта, и он не импортирует ни одного модуля.

Пакет Что в нём
core/database Открытие и миграция обоих файлов SQLite, помощники для запросов, помощники для настроек и событий, общие поля строк, обрезка истории
core/files Помощники для файлов и папок, свободное место на диске
core/releasename Качество, группа и номера серий из имени релиза
core/outbound Единственный способ обращаться к внешним серверам, с проверкой адресов
core/secrets Хранилище ключей и смена ключей
core/logs Журнал приложения и заметки о сбоях
core/jobs Очередь заданий, расписания и циклы, которые перезапускаются после сбоя
core/webserver Обвязка маршрутизатора, URL base, сжатие, живая отправка обновлений
core/startup Пользователь, от которого идёт запуск, режим экономии памяти, переключатели придержанных функций, лимит памяти, Части
core/parts Переключатели Частей, которые каждый модуль проверяет, прежде чем что-то отдавать или запускать
core/model Общие типы, например действующие лица и субъекты

Когда core нужно затронуть данные модуля, модуль регистрирует в core хук в wiring.go. Так работает смена ключей.

Данные
Файл Что в нём
holyarrs.db Медиатека, запросы, настройки и всё остальное важное
holyarrs-events.db История и другие строки событий. Он растёт и обрезается, не трогая основной файл

Миграции — это пронумерованные SQL-файлы в core/database/migrations/main и core/database/migrations/events. Они выполняются при запуске.

HolyArrs бесплатен. Если он сэкономил вам время, поставьте звезду на GitHub, станьте спонсором или угостите меня кофе.