Protocol 14: a warm relay preloads relayed Up next items for everyone

The server keeps one small relay (32 MiB ahead, 8 behind) for Up next's
first relayed item, keyed by its queue id at a URL that stays the same
after the swap: fetched by the server for server-fetch links, fed by
the adder's app for through-me links and files, by a member with an
account for member-passed Jellyfin items. Every app preloads from it;
the swap promotes it with its buffer. Dropped when the item stops
being first or its adder leaves. Measured switch: ~1.6 s cold, 20-40 ms
preloaded. ROADMAP gains the research item on server-side fetching of
member-resolved URLs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
foxyzandClaude Opus 5.5 committed 2026-10-11 17:53:29 +03:00
1 parent e52a7633a0
commit d8585fb78e
17 files changed
+821 -151

No files matched your search

+14 -22
View File
@@ -56,25 +56,19 @@ off by deleting it in the same commit as the code. Wire changes also edit
over instead of the buffer running dry.
- "Bob can't open this link — relay it?": offer the relay to whoever put
a direct link up when a viewer's player fails to open it.
- Preload relayed Up next items (see ARCHITECTURE "Getting ready"):
today a link passed on "through me", another member's file, a
server-fetched link and the host's own file are opened cold by
everyone but their source when they go up (their relay or `/m`
starts with the swap), so the gate waits for the slowest open. Plan
(wire change): the server holds a second, small relay for Up next's
first item, keyed by its queue id. Its adder's app dials a second
source for it as soon as it is first (`/r/.../source` naming the
queue id); a server-fetched item starts its fetch then;
`state.queue[0].relay` (`live`, `tracks`) tells viewers when and
how to open `/r/<sid>/<token>/q/<queueId>/<name>` in their preload
player. The buffer keeps only the head and tail pins plus about
32 MiB ahead of the viewers until the swap, pulls nothing while
nobody preloads, and is dropped when the item stops being first. A
swap with `queueId` turns it into the media's relay (same buffer;
the `q/` URL keeps working for that media, so the preloads match
and are promoted). The host's file: the hosting app hands the
server the first item's path early and `/m` serves it under a
`next/` name until the swap.
- The host's own file as Up next's first item: it plays from `/m`
once up, so others open it cold (the warm relay covers every other
relayed item, see ARCHITECTURE "Relay"). The hosting app could hand
the server the item's path early and `/m` serve it under a `next/`
name until the swap.
- Research (before building anything): can stream URLs a member's
app resolved with yt-dlp (its cookies, its address) be fetched by
the server from another address? Per site: YouTube (its
`googlevideo` URLs carry the resolving IP), Bilibili, X, generic
HLS/DASH, others; and YouTube resolved by the server itself from a
VPS, with and without cookies. Decides whether a server-driven
fetch of member-resolved links (the member need not upload or stay)
is worth building.
8. **Jellyfin** (epic, below).
@@ -98,9 +92,7 @@ off by deleting it in the same commit as the code. Wire changes also edit
- HTTP: move the app's clients (Jellyfin, AniList, AnimeFlow, updater)
to dio from `fox_utils` when touching them, for retries/interceptors.
- TLS: document a reverse proxy in front of the server.
- Up next follow-ups (see ARCHITECTURE "Up next"): getting the first
item ready only resolves its link; fetching its first seconds early
through the relay would make relayed starts instant too. A member
- Up next follow-ups (see ARCHITECTURE "Up next"): a member
whose reconnect lands as a new member loses its "through me" links
and files in the queue (skipped as gone); the key could follow the
member. A whole season or a pick list at once ("Add the rest of the