implement tidal’s (new?) retry-after header for rate-limiting

This commit is contained in:
2025-07-14 14:36:07 +02:00
parent 4c3689016f
commit 2308356c1b

View File

@ -81,6 +81,7 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd
} }
private processTidalHeaders(headers: Headers) { private processTidalHeaders(headers: Headers) {
const retryAfterHeader = headers.get('Retry-After');
const remainingTokens = headers.get('x-ratelimit-remaining'); const remainingTokens = headers.get('x-ratelimit-remaining');
const requiredTokens = headers.get('x-ratelimit-requested-tokens'); const requiredTokens = headers.get('x-ratelimit-requested-tokens');
const replenishRate = headers.get('x-ratelimit-replenish-rate'); const replenishRate = headers.get('x-ratelimit-replenish-rate');
@ -97,6 +98,10 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd
replenishRateValue replenishRateValue
); );
} }
if (retryAfterHeader) {
const retryAfter = parseInt(retryAfterHeader);
this.logger.debug('Tidal rate limit. Retry-After', retryAfter);
}
} }
private async getAlbumItems( private async getAlbumItems(
@ -284,15 +289,25 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd
this.logger.info('Added to playlist', song.tidalUri, song.title); this.logger.info('Added to playlist', song.tidalUri, song.title);
break; break;
case 429: case 429:
const remainingTokens = resp.headers.get('x-ratelimit-remaining'); let secondsToWait = -1;
const requiredTokens = resp.headers.get('x-ratelimit-requested-tokens'); const retryAfterHeader = resp.headers.get('Retry-After');
const replenishRate = resp.headers.get('x-ratelimit-replenish-rate'); if (retryAfterHeader) {
if (remainingTokens !== null && requiredTokens !== null && replenishRate !== null) { secondsToWait = parseInt(retryAfterHeader);
const remainingTokensValue = parseInt(remainingTokens); } else {
const requiredTokensValue = parseInt(requiredTokens); const remainingTokens = resp.headers.get('x-ratelimit-remaining');
const replenishRateValue = parseInt(replenishRate); const requiredTokens = resp.headers.get('x-ratelimit-requested-tokens');
const needToReplenish = requiredTokensValue - remainingTokensValue; const replenishRate = resp.headers.get('x-ratelimit-replenish-rate');
const secondsToWait = 1 + needToReplenish / replenishRateValue; 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( this.logger.warn(
'Received HTTP 429 Too Many Requests. Retrying in', 'Received HTTP 429 Too Many Requests. Retrying in',
secondsToWait, secondsToWait,
@ -302,8 +317,6 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd
setTimeout(() => { setTimeout(() => {
this.addToPlaylistRetry(song, remaning--); this.addToPlaylistRetry(song, remaning--);
}, secondsToWait * 1000); }, secondsToWait * 1000);
} else {
this.logger.warn('Could not read headers how long to wait', resp.headers);
} }
break; break;
default: default: