perf(stalker): classify the static url before authenticating

Codex P2 on #1364. Both static call sites awaited the session warm-up and only
then asked whether the stream needed portal credentials at all — so a movie or
channel on a foreign CDN paid for a handshake whose result was immediately
discarded.

That is not free: non-`create_link` requests carry a 15 s timeout
(`stalker.events.ts`), so a portal that is slow or offline stalled playback of
a stream the CDN would have served instantly. Cold Favorites/Recently Viewed
starts are exactly where this bites, since that is where the session is not
warm already.

Classification now runs first. Foreign host returns immediately, portal-owned
still warms and still falls back to `create_link` without a usable session.
Behaviour is otherwise unchanged; only the order and the wasted wait are gone.

Two tests moved with it: the foreign-host case now asserts the portal is not
contacted at all rather than merely not asked for a link, and the
repaired-endpoint case had been written against a foreign-host command, which
under the new ordering correctly never reaches the handshake it was meant to
be testing — it uses a portal-owned command now.

Mutation-checked: restoring warm-before-classify fails the foreign-host test
alone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 5 committed 2026-08-03 11:24:11 +02:00
1 parent bdf096887b
commit 53f9446b87
5 files changed
+86 -32

No files matched your search

+6
View File
@@ -390,6 +390,12 @@ validates the identity the cached token was negotiated for — which the raw
needed: a simple portal returns immediately and a warm cache with a matching
fingerprint resolves without a request.
The classification happens BEFORE the handshake, not after: a **foreign-host**
static URL never needs the session at all, and warming it anyway would stall
playback behind a request worth up to 15 s against a portal that may be slow
or offline while the CDN is perfectly reachable — for a result that is then
discarded.
The call is best-effort in one direction only. A **foreign-host** static URL
never needed the session, so a failed or skipped handshake still serves it. A
**portal-owned** one with no usable session would be served knowing it will
@@ -900,6 +900,40 @@ describe('StreamResolverService', () => {
expect(playback.headers?.['Authorization']).toBe('Bearer TOKEN-COLD');
});
it('serves a foreign-host static stream without waiting on the portal', async () => {
// The CDN needs no portal credentials, so the handshake would be a
// discarded result — and a stall of up to 15 s when the portal is
// slow or offline but the CDN is fine.
playlistsService.getPlaylistById.mockReturnValue(
of({
_id: 'stalker-1',
portalUrl:
'https://stalker.example.com/stalker_portal/server/load.php',
macAddress: '00:11:22:33:44:55',
isFullStalkerPortal: true,
} satisfies Partial<Playlist>)
);
const playback = await service.resolvePlayback({
uid: 'stalker::stalker-1::94',
name: 'Cdn Channel',
contentType: 'live',
sourceType: 'stalker',
playlistId: 'stalker-1',
playlistName: 'Stalker',
stalkerId: '94',
stalkerCmd: 'ffrt3 https://cdn.example.com/live/94.m3u8',
stalkerItem: {
id: '94',
cmd: 'ffrt3 https://cdn.example.com/live/94.m3u8',
use_http_tmp_link: '0',
},
} as UnifiedCollectionItem);
expect(playback.streamUrl).toBe('https://cdn.example.com/live/94.m3u8');
expect(stalkerSession.ensureToken).not.toHaveBeenCalled();
});
it('still plays a static stream when the session cannot be established', async () => {
// The static URL may point at a CDN that needs no credentials, so a
// failed handshake must not cost the user their playback.
@@ -385,23 +385,29 @@ export class StreamResolverService {
// link; a simple portal returns null immediately. The raw row goes
// in: the helper applies the repair override itself, exactly as
// `executeStalkerRequest` does on the branch below.
const sessionUsable = await this.warmStalkerSession(playlist);
// A foreign-host stream never needed the session. A portal-owned
// one with no usable session would be served knowing it will 401,
// so fall through to `create_link` instead — it mints a URL that
// carries its own token and is the only path that can observe a
// failure and trigger the lazy portal repair.
if (
sessionUsable ||
!isStalkerStreamCredentialSafe(portalUrl, staticUrl)
) {
return this.buildStalkerPlayback(item, playlist, {
//
// Classified BEFORE authenticating: a foreign-host stream never
// needs the session, and warming it anyway would stall playback
// behind a handshake against a portal that may be slow or offline
// while the CDN is perfectly reachable.
const servePlayback = () =>
this.buildStalkerPlayback(item, playlist, {
macAddress,
portalUrl,
streamUrl: staticUrl,
isLive: item.radio === 'true' ? undefined : true,
});
if (!isStalkerStreamCredentialSafe(portalUrl, staticUrl)) {
return servePlayback();
}
// Portal-owned with no usable session would be served knowing it
// will 401, so fall through to `create_link` instead — it mints a
// URL that carries its own token and is the only path that can
// observe a failure and trigger the lazy portal repair.
if (await this.warmStalkerSession(playlist)) {
return servePlayback();
}
}
@@ -254,13 +254,11 @@ describe('stalker-player-request.utils', () => {
);
});
it('serves a foreign-host static url even with no session', async () => {
// A CDN stream never needed the portal session, so a failed or
// skipped handshake must not push it onto the request path.
(stalkerSession.ensureToken as jest.Mock).mockResolvedValue({
token: null,
});
it('serves a foreign-host static url without contacting the portal', async () => {
// A CDN stream never needs the portal session, so it must not be
// pushed onto the request path — and must not wait on a handshake
// either: that is up to 15 s per request against a portal that may
// be offline while the CDN is reachable.
const streamUrl = await fetchStalkerPlaybackLink(deps(), {
playlist: {
...PLAYLIST,
@@ -272,6 +270,7 @@ describe('stalker-player-request.utils', () => {
});
expect(streamUrl).toBe('http://cdn.example/movies/1.mkv');
expect(stalkerSession.ensureToken).not.toHaveBeenCalled();
expect(dataService.sendIpcEvent).not.toHaveBeenCalled();
});
@@ -289,6 +288,11 @@ describe('stalker-player-request.utils', () => {
...stale,
portalUrl: 'http://demo.example/stalker_portal/server/load.php',
} as PlaylistMeta;
// Portal-owned URL: only those reach the handshake now, since a
// foreign host never needs the session.
(stalkerSession.ensureToken as jest.Mock).mockResolvedValue({
token: 'TOKEN-REPAIRED',
});
await fetchStalkerPlaybackLink(
{
@@ -303,7 +307,7 @@ describe('stalker-player-request.utils', () => {
{
playlist: stale,
selectedContentType: 'itv',
cmd: 'ffrt3 http://cdn.example/live/42.m3u8',
cmd: 'ffrt3 http://demo.example/live/42.m3u8',
linkFlags: { use_http_tmp_link: '0' },
}
);
@@ -76,19 +76,13 @@ export async function fetchStalkerPlaybackLink(
// Favorites on a cold start would play a same-host gated stream
// without a Bearer token. Warming at this single choke point
// covers ITV, VOD, radio and downloads alike.
const sessionUsable = await ensureStalkerSession(
deps,
options.playlist
);
// A stream on a foreign host never needed the session, so serve it
// regardless. A portal-owned one with no usable session would be
// served knowing it will 401 — fall back to the request path
// instead, which both mints a URL that carries its own token and
// is the only path that can observe a failure and trigger the
// lazy portal repair.
// Classify BEFORE authenticating. A stream on a foreign host never
// needs the portal session, and warming it anyway would block
// playback behind a handshake worth up to 15 s per request against
// a slow or offline portal (`stalker.events.ts`) for a result that
// is then discarded — the CDN is reachable even when the portal is
// not.
if (
sessionUsable ||
!isStalkerStreamCredentialSafe(
options.playlist.portalUrl ?? '',
staticUrl
@@ -96,6 +90,16 @@ export async function fetchStalkerPlaybackLink(
) {
return staticUrl;
}
// Portal-owned: it may be gated on the Bearer token, and minting
// the link used to be what established the session. Without a
// usable one, serving this would be serving a known 401 — fall
// back to the request path instead, which both mints a URL that
// carries its own token and is the only path that can observe a
// failure and trigger the lazy portal repair.
if (await ensureStalkerSession(deps, options.playlist)) {
return staticUrl;
}
}
}