summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/cmd/listend/main.go24
1 files changed, 24 insertions, 0 deletions
diff --git a/server/cmd/listend/main.go b/server/cmd/listend/main.go
index 3e5c65a..4be69e2 100644
--- a/server/cmd/listend/main.go
+++ b/server/cmd/listend/main.go
@@ -182,6 +182,26 @@ func (w *worker) run(ctx context.Context, every time.Duration) {
}
}
+// drainRequests serves everything the phone has asked for, without waiting.
+//
+// Bounds how long an on-demand episode waits at one feed rather than one cycle. It does not make
+// the wait short -- a feed carrying detection takes minutes -- but the phone falls back to the
+// publisher meanwhile, so the cost of waiting is skip offsets rather than playback.
+func (w *worker) drainRequests(ctx context.Context) {
+ for {
+ if ctx.Err() != nil {
+ return
+ }
+ select {
+ case req := <-w.requests:
+ w.serveRequest(ctx, req)
+ w.save()
+ default:
+ return
+ }
+ }
+}
+
func (w *worker) save() {
if err := w.state.Save(w.statePath); err != nil {
log.Printf("save: %v", err)
@@ -199,6 +219,10 @@ func (w *worker) pollAll(ctx context.Context) {
if ctx.Err() != nil {
return
}
+ // Before each feed, not only between cycles. The poll loop and the request queue share
+ // one goroutine, so an episode the phone asked for used to wait out the entire cycle --
+ // hours across 42 shows, during which a tap on an unmirrored episode did nothing at all.
+ w.drainRequests(ctx)
w.pollOne(ctx, feedURL)
// After every feed rather than at the end of the cycle: a cycle over 61 feeds takes
// hours, and a restart partway through used to discard all of it.