跳到內容

架構

進階

在做大型變更之前,先找出程式碼放在哪裡、適用哪些規則。

HolyArrs 是一個內建 Web 介面的 Go 程式。它在 port 6262 提供 Web App 和 JSON API,並把資料存在設定資料夾裡的 2 個 SQLite 檔案中。它會連到下載器、來源(透過 Jackett 或 Prowlarr)、媒體伺服器、通知管道,以及 HolyArrs metadata 伺服器。

來看一個請求的流程。有人在「探索」頁面請求一部電影。

  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 放在 repo 根目錄,因為 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
App 的哪些功能區塊已開啟 internal/core/parts
頁面位址 app/frontend/src/routes/
一個 migration internal/core/database/migrations/
Docker image deploy/Dockerfile

只要有一條規則被打破,app/backend/tools/structurecheck 裡的檢查就會讓建置失敗。用 測試 裡的那一行指令執行它們。

  • 層級順序。 一個模組只能匯入較低層級的模組,而且只能匯入它們的根 package。同一層的模組絕不互相匯入。
  • 向上呼叫。 較低的模組需要較高模組的東西時,由較高的模組把單純的資料往下傳,或由較低的模組定義一個小介面,再由 wiring.go 填入。
  • SQL 只留在自己家。 只有模組自己的 store*.go 檔案可以放 SQL,而且只能操作它自己的資料表。要讀別的模組的資料列,就呼叫它的 service。
  • 共用資料表屬於 core。 透過 core 的輔助函式存取 settings、schedules、secrets、jobs 和 events。
  • 只有一個出口。 所有對外的呼叫都經過 core/outbound。
  • 暫緩的功能 會向 core/startup 註冊一個開關。開關關閉時,路由不存在,頁面也會隱藏這個功能。
  • 不要有雜物箱式的 package。 不要用 util、common、shared 或 helpers。

層級順序在 模組 裡。

模組內部

每個後端模組都使用相同的檔名。

檔案 內容
routes.go API 路由,每個都附上它需要的權限
service.go 和各主題檔案 其他模組會呼叫的邏輯
store.go、store_<topic>.go 模組自己資料表的所有 SQL
types.go 模組的資料記錄

在 Web 端,lib/<module>/ 放著 index.ts(其他模組可以使用的部分)、它的 Svelte 元件和測試,只有在有自己的呼叫或狀態時才會有 api.ts 和 state.svelte.ts。

Core packages

Core 是基礎設施。它不放任何產品規則,也不匯入任何模組。

Package 內容
core/database 開啟並 migrate 兩個 SQLite 檔案、查詢輔助函式、設定與事件的輔助函式、共用的資料列欄位、歷史記錄修剪
core/files 檔案與資料夾的輔助函式、可用磁碟空間
core/releasename 從發行版名稱取出品質、群組和集數
core/outbound 呼叫外部伺服器的唯一管道,附帶位址檢查
core/secrets 金鑰儲存區與金鑰輪替
core/logs App 的 log 和當機紀錄
core/jobs 工作佇列、排程,以及當機後會重新啟動的迴圈
core/webserver 路由基礎設施、URL base、壓縮、即時推送
core/startup 執行身分、低記憶體模式、暫緩功能的開關、記憶體上限、功能區塊
core/parts 各模組在提供服務或執行之前會先詢問的功能區塊開關
core/model 共用的型別,例如 actor 和 subject

Core 一定要碰模組的資料時,由模組在 wiring.go 裡向 core 註冊一個 hook。金鑰輪替就是這樣運作的。

資料
檔案 內容
holyarrs.db 媒體庫、請求、設定,以及其他所有重要的資料
holyarrs-events.db 歷史記錄和其他事件資料列。它會持續成長,也能在不動到主檔案的情況下修剪

Migration 是依編號排列的 SQL 檔案,放在 core/database/migrations/main 和 core/database/migrations/events。它們在啟動時執行。

HolyArrs 是免費的。如果它幫你省下了時間,歡迎在 GitHub 上給顆星、贊助專案,或請我喝杯咖啡。