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 { // 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 сохраняет задачу, захват которой держит 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) }