From 2308356c1b090b9cd3b8850cee4055f6af9e0aeb Mon Sep 17 00:00:00 2001 From: Max Nuding Date: Mon, 14 Jul 2025 14:36:07 +0200 Subject: [PATCH] =?UTF-8?q?implement=20tidal=E2=80=99s=20(new=3F)=20retry-?= =?UTF-8?q?after=20header=20for=20rate-limiting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/server/playlist/tidalPlaylistAdder.ts | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/lib/server/playlist/tidalPlaylistAdder.ts b/src/lib/server/playlist/tidalPlaylistAdder.ts index 9b46d79..d1dfaa6 100644 --- a/src/lib/server/playlist/tidalPlaylistAdder.ts +++ b/src/lib/server/playlist/tidalPlaylistAdder.ts @@ -81,6 +81,7 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd } private processTidalHeaders(headers: Headers) { + const retryAfterHeader = headers.get('Retry-After'); const remainingTokens = headers.get('x-ratelimit-remaining'); const requiredTokens = headers.get('x-ratelimit-requested-tokens'); const replenishRate = headers.get('x-ratelimit-replenish-rate'); @@ -97,6 +98,10 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd replenishRateValue ); } + if (retryAfterHeader) { + const retryAfter = parseInt(retryAfterHeader); + this.logger.debug('Tidal rate limit. Retry-After', retryAfter); + } } private async getAlbumItems( @@ -284,15 +289,25 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd this.logger.info('Added to playlist', song.tidalUri, song.title); break; case 429: - const remainingTokens = resp.headers.get('x-ratelimit-remaining'); - const requiredTokens = resp.headers.get('x-ratelimit-requested-tokens'); - const replenishRate = resp.headers.get('x-ratelimit-replenish-rate'); - if (remainingTokens !== null && requiredTokens !== null && replenishRate !== null) { - const remainingTokensValue = parseInt(remainingTokens); - const requiredTokensValue = parseInt(requiredTokens); - const replenishRateValue = parseInt(replenishRate); - const needToReplenish = requiredTokensValue - remainingTokensValue; - const secondsToWait = 1 + needToReplenish / replenishRateValue; + let secondsToWait = -1; + const retryAfterHeader = resp.headers.get('Retry-After'); + if (retryAfterHeader) { + secondsToWait = parseInt(retryAfterHeader); + } else { + const remainingTokens = resp.headers.get('x-ratelimit-remaining'); + const requiredTokens = resp.headers.get('x-ratelimit-requested-tokens'); + const replenishRate = resp.headers.get('x-ratelimit-replenish-rate'); + if (remainingTokens !== null && requiredTokens !== null && replenishRate !== null) { + const remainingTokensValue = parseInt(remainingTokens); + const requiredTokensValue = parseInt(requiredTokens); + const replenishRateValue = parseInt(replenishRate); + const needToReplenish = requiredTokensValue - remainingTokensValue; + secondsToWait = 1 + needToReplenish / replenishRateValue; + } + } + if (secondsToWait === -1) { + this.logger.warn('Could not read headers how long to wait', resp.headers); + } else { this.logger.warn( 'Received HTTP 429 Too Many Requests. Retrying in', secondsToWait, @@ -302,8 +317,6 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd setTimeout(() => { this.addToPlaylistRetry(song, remaning--); }, secondsToWait * 1000); - } else { - this.logger.warn('Could not read headers how long to wait', resp.headers); } break; default: