mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
42 lines
1.9 KiB
JavaScript
42 lines
1.9 KiB
JavaScript
import { update } from "../../core/signals/primitives.js";
|
|
import { findTrackById } from "../../media/utils/tracks.js";
|
|
import { addFailedCdn, getCdnId } from "../../media/utils/cdn.js";
|
|
//#region src/playback/primitives/failover-fetch.ts
|
|
/**
|
|
* Decorate a fetch so a failed request trips the **selected track's** CDN into
|
|
* `failedCdns`. The decorated fetch's type is preserved, so this wraps both
|
|
* `resolve-track`'s playlist `FetchText` and the segment loaders' `FetchBytes`.
|
|
*
|
|
* The CDN id comes from the selected track's media-playlist URL, never the
|
|
* failed addressable: a segment URL resolves relative to its playlist and, per
|
|
* RFC 3986, drops the playlist's query string (`…/r.m3u8?cdn=fastly` → `…/0.ts`),
|
|
* so a query-keyed `getCdnId` (e.g. Mux's `cdn=`) keyed on it would derive an id
|
|
* that never matches the ones `deriveCdnPriority` / track-switching build from
|
|
* `track.url`. The in-flight fetch belongs to the selected track — a source or
|
|
* track switch aborts it, and aborts don't trip — so the selected track is the
|
|
* right CDN to fail over. For `resolve-track` the resolving track *is* the
|
|
* selected track, so this is identical to keying on its addressable.
|
|
*
|
|
* No-op when no failover monitor is composed (it owns the signal) or the
|
|
* selected track can't be located.
|
|
*/
|
|
function failoverFetch(baseFetch, state, config) {
|
|
const getCdnId$1 = config.getCdnId ?? getCdnId;
|
|
return (async (addressable, options) => {
|
|
try {
|
|
return await baseFetch(addressable, options);
|
|
} catch (error) {
|
|
if (!options?.signal?.aborted && state.failedCdns) {
|
|
const presentation = state.presentation.get();
|
|
const trackId = state[config.selectedKey].get();
|
|
const track = presentation && trackId ? findTrackById(presentation, trackId) : void 0;
|
|
if (track) update(state.failedCdns, (cdns) => addFailedCdn(cdns, getCdnId$1(track.url)));
|
|
}
|
|
throw error;
|
|
}
|
|
});
|
|
}
|
|
//#endregion
|
|
export { failoverFetch };
|
|
|
|
//# sourceMappingURL=failover-fetch.js.map
|