diff --git a/internal/adapters/transcribe/timeout.go b/internal/adapters/transcribe/timeout.go new file mode 100644 index 0000000..fee7b1b --- /dev/null +++ b/internal/adapters/transcribe/timeout.go @@ -0,0 +1,33 @@ +package transcribe + +import ( + "context" + "time" + + "git.d-ma.be/mathias/tapir/internal/domain" +) + +// WithTimeout gives every call to b its own deadline. A wedged engine does not answer at +// all (iguana after a Metal OOM, infra#273), and with only the job's deadline it used up +// the whole job before a fallback could run -- and Chain then refuses the fallback because +// the job context has expired. With its own deadline the call fails while the job is still +// alive, which is exactly when the fallback, or the other engine, can take over. +// +// A zero or negative d returns b unchanged. The wrapper is invisible: Name is b's. +func WithTimeout(b Backend, d time.Duration) Backend { + if d <= 0 { + return b + } + return timeoutBackend{Backend: b, d: d} +} + +type timeoutBackend struct { + Backend + d time.Duration +} + +func (t timeoutBackend) Transcribe(ctx context.Context, wavPath string) (domain.Transcription, error) { + ctx, cancel := context.WithTimeout(ctx, t.d) + defer cancel() + return t.Backend.Transcribe(ctx, wavPath) +}