package entity import ( "time" ) type TranscribeJob struct { Id string State string Source string FileID *string ErrorText *string AcquisitionID *string AcquireTime *time.Time DelayTime *time.Time Attempts int // Число попыток: растёт при захвате, обнуляется на шаге без отказа RecognitionOpID *string // ID операции распознавания в Yandex Cloud TranscriptionText *string // Результат распознавания TgChatId *int64 // Telegram: в какой чат отправить результат распознавания TgReplyMessageId *int // Telegram: с каким сообщением связать результат распознавания CreatedAt time.Time UpdatedAt time.Time } const ( StateCreated = "created" StateConverted = "converted" StateTranscribe = "transcribe" StateDone = "done" StateFailed = "failed" // StateDead — задача, которую мы повторяли и перестали. От `failed` она // отличается тем, чей это приговор: в `failed` задачу переводит шаг, // рассудивший об этой записи окончательно, а сюда она уходит без такого // суждения. Ни один шаг конвейера в неё не переводит сам. StateDead = "dead" ) const ( SourceUnknown = "unknown" SourceApi = "api" SourceTelegram = "telegram" ) // Переводит задачу в новое состояние, при этом очищает все // служебные поля предыдущего состояния, как-то время задержки, информацию о воркере и тд func (j *TranscribeJob) MoveToState(state string) { j.State = state j.DelayTime = nil j.AcquisitionID = nil j.AcquireTime = nil // Шаг, дошедший до перехода, завершился без отказа, а попытки считают // именно отказавшие: иначе задача, прошедшая конвейер целиком, накопила бы // их поштучно и умерла бы здоровой. j.Attempts = 0 j.UpdatedAt = time.Now() } func (j *TranscribeJob) MoveToStateAndDelay(state string, delay *time.Time) { j.MoveToState(state) j.DelayTime = delay j.UpdatedAt = time.Now() } func (j *TranscribeJob) Done(transcriptionText string) { j.MoveToState(StateDone) j.TranscriptionText = &transcriptionText } func (j *TranscribeJob) Fail(errText string) { j.MoveToState(StateFailed) j.ErrorText = &errText } // RetryAfter освобождает отказавшую задачу для повтора: захват снимается, // пауза ставится, а число попыток сохраняется — по нему растёт пауза и // наступает предел. func (j *TranscribeJob) RetryAfter(delay time.Time) { j.AcquisitionID = nil j.AcquireTime = nil j.DelayTime = &delay j.UpdatedAt = time.Now() } // Die переводит задачу, исчерпавшую попытки, в состояние «мертва». Число // попыток при этом сохраняется: по нему видно, сколько раз мы пробовали, а // возвращает задачу в работу владелец правкой состояния. func (j *TranscribeJob) Die(errText string) { attempts := j.Attempts j.MoveToState(StateDead) j.Attempts = attempts j.ErrorText = &errText }