хранилище, файлы записей и очередь переведены на встроенную PocketBase
- записи, метаданные и файлы съехались под один каталог данных; появилась панель владельца, а gin, goqu, goose и требование CGO ушли - захват задачи стал одним запросом с RETURNING; заведены число попыток, состояние dead и нарастающая пауза вместо признака is_error - имя файла в хранилище задаёт сервис и в журнал не идёт: вместе с идентификатором записи оно собирало бы ссылку на скачивание
This commit is contained in:
@@ -11,6 +11,18 @@ func (e *JobNotFoundError) Error() string {
|
||||
return fmt.Sprintf("%s - %s", e.State, e.Message)
|
||||
}
|
||||
|
||||
// LostAcquisitionError — захват задачи за время работы шага достался другому.
|
||||
// Шаг, получивший его, завершается без записи результата и без ответа
|
||||
// отправителю: иначе два воркера пишут в одну задачу по очереди, а отправитель
|
||||
// получает два ответа на одну запись.
|
||||
type LostAcquisitionError struct {
|
||||
JobID string
|
||||
}
|
||||
|
||||
func (e *LostAcquisitionError) Error() string {
|
||||
return fmt.Sprintf("%s: job acquisition lost", e.JobID)
|
||||
}
|
||||
|
||||
type NoopJobError struct {
|
||||
State string
|
||||
}
|
||||
|
||||
@@ -1,19 +1,58 @@
|
||||
package contract
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"git.vakhrushev.me/av/transcriber/internal/entity"
|
||||
)
|
||||
|
||||
// WorkFile — рабочая копия файла на диске: её просят шаги, отдающие файл
|
||||
// внешней программе, потому что `ffmpeg` и `ffprobe` принимают имя аргументом.
|
||||
//
|
||||
// Заводится копия одним способом — репозиторием файлов, — и убирает её за собой
|
||||
// Close. Каждый шаг, заводящий копию сам, повторял бы и обязанность прибрать, а
|
||||
// забытая копия это шестичасовая запись во временном каталоге, о которой не
|
||||
// узнает никто.
|
||||
type WorkFile interface {
|
||||
// Path — имя копии на диске, годное для внешней программы.
|
||||
Path() string
|
||||
// Size — длина копии в байтах на момент вызова.
|
||||
Size() (int64, error)
|
||||
// Close убирает копию. Зовётся на любом исходе, включая отказ.
|
||||
Close() error
|
||||
}
|
||||
|
||||
type FileRepository interface {
|
||||
Create(file *entity.File) error
|
||||
// Stage принимает содержимое потоком в рабочую копию с заданным
|
||||
// расширением: по нему внешняя программа выбирает разбор. В память запись
|
||||
// целиком не читается — расчётный потолок шесть часов.
|
||||
Stage(ext string, content io.Reader) (WorkFile, error)
|
||||
// StageEmpty заводит пустую рабочую копию с заданным расширением — под
|
||||
// результат внешней программы, которая пишет по имени.
|
||||
StageEmpty(ext string) (WorkFile, error)
|
||||
// Localize выдаёт рабочую копию хранимого файла.
|
||||
Localize(fileID string) (WorkFile, error)
|
||||
// CreateLocal кладёт рабочую копию в хранилище под именем name и заводит
|
||||
// запись о файле. Имя задаёт сервис: умолчание хранилища, строящее его из
|
||||
// имени отправителя, не применяется.
|
||||
CreateLocal(name string, work WorkFile) (*entity.File, error)
|
||||
// CreateRemote заводит запись о копии, лежащей во внешнем хранилище.
|
||||
CreateRemote(objectKey string, size int64) (*entity.File, error)
|
||||
GetByID(id string) (*entity.File, error)
|
||||
// Open отдаёт содержимое хранимого файла потоком.
|
||||
Open(fileID string) (io.ReadCloser, error)
|
||||
}
|
||||
|
||||
type TranscriptJobRepository interface {
|
||||
Create(job *entity.TranscribeJob) error
|
||||
Save(job *entity.TranscribeJob) error
|
||||
// Save сохраняет задачу, захват которой держит holder. Захват, доставшийся
|
||||
// за время работы другому, даёт LostAcquisitionError и запись не проводит.
|
||||
// Пустой holder снимает эту условность и в конвейере не употребляется: все
|
||||
// его шаги получают признак захвата от FindAndAcquire.
|
||||
Save(job *entity.TranscribeJob, holder string) error
|
||||
GetByID(id string) (*entity.TranscribeJob, error)
|
||||
// FindAndAcquire забирает задачу одним неделимым шагом и увеличивает число
|
||||
// её попыток. Работы в состоянии нет — JobNotFoundError.
|
||||
FindAndAcquire(state, acquisitionId string, rottingTime time.Time) (*entity.TranscribeJob, error)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user