* feat(playback): formalize resumable direct streams and stall observability Implements #443: strong stat-based ETag + If-Range on original-file direct play (via http.ServeContent), stream-end outcome classification in RollingDeadlineWriter (stalled_reap vs client_gone vs completed) with a structured log event and Prometheus counters, the direct_stream_resume_v1 protocol-v3 capability, and a contract doc. Progressive remux is explicitly excluded from the resume contract. Code written by OpenAI Codex CLI (gpt-5.6-sol) from a Claude-authored spec; reviewed and verified by Claude. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(playback): harden direct stream resume contract * test(playback): cover resume platform contracts --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
45 lines
1.6 KiB
Go
45 lines
1.6 KiB
Go
package playback
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/Silo-Server/silo-server/internal/httpstream"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
|
)
|
|
|
|
var (
|
|
directStreamActive = promauto.NewGauge(prometheus.GaugeOpts{
|
|
Name: "silo_direct_stream_active",
|
|
Help: "Number of original-file direct streams currently being served.",
|
|
})
|
|
directStreamEnds = promauto.NewCounterVec(prometheus.CounterOpts{
|
|
Name: "silo_direct_stream_ends_total",
|
|
Help: "Number of original-file direct streams by terminal outcome.",
|
|
}, []string{"outcome"})
|
|
directStreamRangeResumes = promauto.NewCounter(prometheus.CounterOpts{
|
|
Name: "silo_direct_stream_range_resumes_total",
|
|
Help: "Number of successful original-file byte-range resumes after byte zero.",
|
|
})
|
|
directStreamInvalidRanges = promauto.NewCounter(prometheus.CounterOpts{
|
|
Name: "silo_direct_stream_invalid_range_total",
|
|
Help: "Number of original-file direct stream requests rejected with HTTP 416.",
|
|
})
|
|
directStreamBytesSent = promauto.NewCounter(prometheus.CounterOpts{
|
|
Name: "silo_direct_stream_bytes_sent_total",
|
|
Help: "Number of original-file direct stream response body bytes sent.",
|
|
})
|
|
)
|
|
|
|
func recordDirectStreamEnd(outcome httpstream.StreamOutcome, status int, bytesSent, rangeStart int64) {
|
|
directStreamActive.Dec()
|
|
directStreamEnds.WithLabelValues(string(outcome)).Inc()
|
|
directStreamBytesSent.Add(float64(bytesSent))
|
|
if status == http.StatusPartialContent && rangeStart > 0 {
|
|
directStreamRangeResumes.Inc()
|
|
}
|
|
if status == http.StatusRequestedRangeNotSatisfiable {
|
|
directStreamInvalidRanges.Inc()
|
|
}
|
|
}
|