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

+4 -4
View File
@@ -94,7 +94,7 @@ class SyncServer {
);
});
mountSessionMediaRoute(_app, sessions);
mountRelayRoutes(_app, sessions, () => hub.relay);
mountRelayRoutes(_app, sessions, relayAt: hub.relayAt, sourceOf: hub.sourceOf);
mountAvatarRoute(_app, hub);
mountArtRoute(_app, hub);
mountJellyfinRelayRoute(
@@ -108,8 +108,8 @@ class SyncServer {
return 'http://${authority(dialledHost)}/m/$sid/$token/$name';
}, relayUrlBuilder: (sid, token, itemId, dialledHost) =>
'http://${authority(dialledHost)}/j/$sid/$token/${Uri.encodeComponent(itemId)}',
relayMediaUrlBuilder: (sid, token, mediaId, name, tracks, dialledHost) =>
relayViewerUrl('http://${authority(dialledHost)}/r/$sid/$token/$mediaId', name, tracks: tracks));
relayMediaUrlBuilder: (sid, token, key, name, tracks, dialledHost) =>
relayViewerUrl('http://${authority(dialledHost)}/r/$sid/$token/$key', name, tracks: tracks));
_app.fallback = (final req) => Response.notFound(
body: Body.fromString('not found'),
);
@@ -181,7 +181,7 @@ class SyncServer {
_heartbeat = null;
_relayClient?.close(force: true);
_relayClient = null;
hub.setRelay(null);
hub.dropRelays();
await hub.closeAllSockets();
await _app.close();
_server = null;