From b7ab09f9a17db0854c35fea3cb6638e090ce4c14 Mon Sep 17 00:00:00 2001 From: Igor Zolotarenko Date: Fri, 29 Dec 2023 14:22:40 +0200 Subject: [PATCH] Failed attempts clear interval. --- .../src/hybrid-loader.ts | 27 ++++++++++++++----- .../src/request-container.ts | 4 --- packages/p2p-media-loader-core/src/request.ts | 13 ++++++++- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/packages/p2p-media-loader-core/src/hybrid-loader.ts b/packages/p2p-media-loader-core/src/hybrid-loader.ts index 9b9841a6..a49ca462 100644 --- a/packages/p2p-media-loader-core/src/hybrid-loader.ts +++ b/packages/p2p-media-loader-core/src/hybrid-loader.ts @@ -12,6 +12,8 @@ import * as StreamUtils from "./utils/stream"; import * as Utils from "./utils/utils"; import debug from "debug"; +const FAILED_ATTEMPTS_CLEAR_INTERVAL = 60000; + export class HybridLoader { private readonly requests: RequestsContainer; private readonly p2pLoaders: P2PLoadersContainer; @@ -127,6 +129,7 @@ export class HybridLoader { private processRequests(queueSegmentIds: Set) { const { stream } = this.lastRequestedSegment; const { httpErrorRetries } = this.settings; + const now = performance.now(); for (const request of this.requests.items()) { const { type, @@ -187,6 +190,12 @@ export class HybridLoader { break; } request.markHandledByProcessQueue(); + if ( + now - request.failedAttempts.lastClearTimestamp > + FAILED_ATTEMPTS_CLEAR_INTERVAL + ) { + request.failedAttempts.clear(); + } } } @@ -294,7 +303,7 @@ export class HybridLoader { } private loadRandomThroughHttp() { - const { simultaneousHttpDownloads } = this.settings; + const { simultaneousHttpDownloads, httpErrorRetries } = this.settings; const p2pLoader = this.p2pLoaders.currentLoader; const connectedPeersAmount = p2pLoader.connectedPeersAmount; if ( @@ -307,11 +316,17 @@ export class HybridLoader { lastRequestedSegment: this.lastRequestedSegment, playback: this.playback, settings: this.settings, - skipSegment: (segment, statuses) => - !statuses.isHttpDownloadable || - this.segmentStorage.hasSegment(segment) || - this.requests.isHybridLoaderRequested(segment) || - p2pLoader.isLoadingOrLoadedBySomeone(segment), + skipSegment: (segment, statuses) => { + const request = this.requests.get(segment); + return ( + !statuses.isHttpDownloadable || + this.segmentStorage.hasSegment(segment) || + request?.type !== undefined || + (request?.failedAttempts.httpAttemptsCount ?? 0) >= + httpErrorRetries || + p2pLoader.isLoadingOrLoadedBySomeone(segment) + ); + }, }); if (!queue.length) return; const peersAmount = connectedPeersAmount + 1; diff --git a/packages/p2p-media-loader-core/src/request-container.ts b/packages/p2p-media-loader-core/src/request-container.ts index 14d332e0..46987820 100644 --- a/packages/p2p-media-loader-core/src/request-container.ts +++ b/packages/p2p-media-loader-core/src/request-container.ts @@ -73,10 +73,6 @@ export class RequestsContainer { } } - isHybridLoaderRequested(segment: Segment): boolean { - return !!this.requests.get(segment)?.type; - } - destroy() { for (const request of this.requests.values()) { request.abortFromProcessQueue(); diff --git a/packages/p2p-media-loader-core/src/request.ts b/packages/p2p-media-loader-core/src/request.ts index 2657154c..a2f525eb 100644 --- a/packages/p2p-media-loader-core/src/request.ts +++ b/packages/p2p-media-loader-core/src/request.ts @@ -139,6 +139,7 @@ export class Request { if (this._engineCallbacks) { throw new Error("Segment is already requested by engine"); } + this.failedAttempts.clear(); this._isHandledByProcessQueue = false; this._engineCallbacks = callbacks; } @@ -311,7 +312,12 @@ export class Request { } class FailedRequestAttempts { - private readonly attempts: RequestAttempt[] = []; + private attempts: RequestAttempt[] = []; + private _lastClearTimestamp = performance.now(); + + get lastClearTimestamp() { + return this._lastClearTimestamp; + } add(attempt: RequestAttempt) { this.attempts.push(attempt); @@ -323,6 +329,11 @@ class FailedRequestAttempts { 0 ); } + + clear() { + this.attempts = []; + this._lastClearTimestamp = performance.now(); + } } const requestInnerErrorTypes = ["abort", "bytes-receiving-timeout"] as const;