feat(stream): report watch progress to API via HTTP Range tracking

Track the highest byte offset served by the stream server to estimate
playback progress (0-100%). A WatchReporter goroutine sends progress
to POST /api/internal/agent/watch-progress every 10s during streaming.

- Add maxByteOffset + totalFileSize to StreamServer for Range tracking
- Add FileSize() to fileProvider interface (all 3 providers)
- New WatchReporter: periodic progress reporter tied to daemon context
- New WatchProgressUpdate type with optional progress/position/duration
- Wire reporter into all 3 stream paths (task stream, disk stream, active download stream)
This commit is contained in:
Deivid Soto 2026-04-01 12:16:45 +02:00
parent 932312fc56
commit 0dafeaa70d
8 changed files with 366 additions and 10 deletions

View file

@ -55,7 +55,7 @@ func cancelStreamTask(taskID string) {
// handleStreamTask manages a streaming task lifecycle outside the Manager.
// It creates a StreamEngine, buffers, starts an HTTP server, and reports
// progress until the task is cancelled or the download completes.
func handleStreamTask(parentCtx context.Context, at agent.Task, reporter *engine.ProgressReporter, cfg config.Config) {
func handleStreamTask(parentCtx context.Context, at agent.Task, reporter *engine.ProgressReporter, cfg config.Config, agentClient *agent.Client) {
ctx, cancel := context.WithCancel(parentCtx)
defer cancel()
@ -121,6 +121,12 @@ func handleStreamTask(parentCtx context.Context, at agent.Task, reporter *engine
task.StreamURL = streamURL
log.Printf("[%s] stream ready: %s", at.ID[:8], streamURL)
// 5b. Start watch progress reporter (tracks Range requests for playback position)
if agentClient != nil {
watchReporter := engine.NewWatchReporter(agentClient, srv, at.ID)
go watchReporter.Run(ctx)
}
// 6. Unified progress + idle timeout loop
eng.StartProgressLoop(ctx)
progressTicker := time.NewTicker(3 * time.Second)