- записи, метаданные и файлы съехались под один каталог данных; появилась панель владельца, а gin, goqu, goose и требование CGO ушли - захват задачи стал одним запросом с RETURNING; заведены число попыток, состояние dead и нарастающая пауза вместо признака is_error - имя файла в хранилище задаёт сервис и в журнал не идёт: вместе с идентификатором записи оно собирало бы ссылку на скачивание
57 lines
2.7 KiB
Go
57 lines
2.7 KiB
Go
// Package pocketbase — хранилище задач и файлов поверх встроенной PocketBase.
|
|
//
|
|
// Приложение поднимается библиотекой, а не её набором команд: разбор флагов и
|
|
// мягкая остановка остаются нашими, а ключ `-c config.toml` — объявленный
|
|
// контракт запуска.
|
|
package pocketbase
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
pb "github.com/pocketbase/pocketbase"
|
|
"github.com/pocketbase/pocketbase/core"
|
|
)
|
|
|
|
// Имена коллекций. Они же — часть пути к файлу в раскладке хранилища и часть
|
|
// адреса ссылки на него, поэтому меняются только новым шагом схемы.
|
|
const (
|
|
FilesCollection = "files"
|
|
JobsCollection = "transcribe_jobs"
|
|
)
|
|
|
|
// New создаёт приложение хранилища на заданном каталоге данных и приводит его в
|
|
// рабочее состояние: открывает базу, читает настройки и накатывает непринятые
|
|
// шаги схемы.
|
|
//
|
|
// Схема накатывается **здесь**, а не оставляется серверу, хотя тот и гоняет
|
|
// непринятые шаги сам. Причина в порядке: воркеры стартуют раньше сервера, и на
|
|
// чистом каталоге их первые опросы приходились бы на несуществующую таблицу —
|
|
// отказ в журнале и в счётчике на каждую секунду до конца накатки.
|
|
func New(dataDir string) (*pb.PocketBase, error) {
|
|
app := pb.NewWithConfig(pb.Config{
|
|
DefaultDataDir: dataDir,
|
|
HideStartBanner: true,
|
|
})
|
|
|
|
if err := app.Bootstrap(); err != nil {
|
|
return nil, fmt.Errorf("failed to bootstrap storage: %w", err)
|
|
}
|
|
|
|
if err := app.RunAllMigrations(); err != nil {
|
|
return nil, fmt.Errorf("failed to apply storage schema: %w", err)
|
|
}
|
|
|
|
return app, nil
|
|
}
|
|
|
|
// MustFindCollection достаёт коллекцию по имени. Отсутствие коллекции здесь —
|
|
// не отказ окружения, а несделанный шаг схемы: сервис до этой точки не доходит,
|
|
// потому что Serve накатывает схему прежде, чем поднять сервер.
|
|
func findCollection(app core.App, name string) (*core.Collection, error) {
|
|
collection, err := app.FindCollectionByNameOrId(name)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to find collection %s: %w", name, err)
|
|
}
|
|
return collection, nil
|
|
}
|