diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-06 15:43:04 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-06 15:43:04 +0300 |
| commit | cdb5951fa25cc9352128ee8c0d76027cf2f6aa92 (patch) | |
| tree | a6adec2155464831d61be27cea00ac2a53a6b99c | |
| parent | 7193ec765f0b51093a203f8f3d00e69008be1cce (diff) | |
chore: bump version to 0.21.0, add maxPollAttempts constant and comments to veo.go
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| -rw-r--r-- | internal/version.go | 2 | ||||
| -rw-r--r-- | internal/video/veo.go | 20 |
2 files changed, 18 insertions, 4 deletions
diff --git a/internal/version.go b/internal/version.go index 4c6daf1..ea3a538 100644 --- a/internal/version.go +++ b/internal/version.go @@ -1,3 +1,3 @@ package internal -const Version = "0.20.0" +const Version = "0.21.0" diff --git a/internal/video/veo.go b/internal/video/veo.go index ba23c74..c3be521 100644 --- a/internal/video/veo.go +++ b/internal/video/veo.go @@ -21,14 +21,23 @@ const ( DefaultVeoModel = "veo-2.0-generate-001" // videoDurationSeconds is the clip length requested from Veo. + // 8 seconds is the minimum duration supported by the Veo API and produces + // clips long enough to convey the flashcard content without excess. videoDurationSeconds = int32(8) // videoAspectRatio is the target aspect ratio for generated clips. + // 16:9 matches the landscape orientation of the comic-style gallery panels. videoAspectRatio = "16:9" // pollInterval is the time to wait between operation status checks. // Veo generation typically takes 1–3 minutes; 15 s keeps polling overhead low. pollInterval = 15 * time.Second + + // maxPollAttempts caps the number of polling iterations so that a hung or + // stalled Veo operation does not block the process indefinitely. + // At 15 s per attempt, 40 attempts ≈ 10 minutes — well above the observed + // worst-case generation time of ~3 minutes. + maxPollAttempts = 40 ) // VeoGenerator wraps the Google GenAI client for Veo video generation. @@ -219,10 +228,15 @@ func (g *VeoGenerator) startOperation(ctx context.Context, imgBytes []byte, prom } // pollUntilDone repeatedly calls GetVideosOperation until the operation reports -// completion or the context is cancelled. It sleeps pollInterval between checks. +// completion, the context is cancelled, or maxPollAttempts is reached. +// It sleeps pollInterval between checks to avoid hammering the API. func (g *VeoGenerator) pollUntilDone(ctx context.Context, op *genai.GenerateVideosOperation) (*genai.GenerateVideosOperation, error) { - for !op.Done { - log.Printf("veo: operation in progress, waiting %s...", pollInterval) + for attempt := 0; !op.Done; attempt++ { + if attempt >= maxPollAttempts { + return nil, fmt.Errorf("veo: operation did not complete after %d attempts (%s each)", maxPollAttempts, pollInterval) + } + + log.Printf("veo: operation in progress, waiting %s (attempt %d/%d)...", pollInterval, attempt+1, maxPollAttempts) select { case <-ctx.Done(): |
