mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-27 03:41:47 +02:00
perf(network): mobile stability and data-usage fixes from network audit
Stability: - transient timeouts no longer classified as ISP blocking; they fall through to retry backoff (hard blocks - DNS/RST/cert - still abort) - connectivity change now closes idle Go connections in every network mode (debounced), so pooled sockets from the old interface are not reused after a wifi/cellular handoff - download body reads get a 60s stall watchdog that cancels and surfaces a retryable network error instead of hanging; distinct from user cancellation - ResponseHeaderTimeout 45s on all transports; IdleConnTimeout 90->60s; dial timeout 30->10s; retry backoff gains full jitter; Retry-After honored on 5xx and Deezer 429 Data usage / speed: - cover downloads deduplicated with singleflight plus a 24MB/15min in-memory cache keyed by final URL (album batches fetched the same 1800px cover once per track before) - song.link availability cached (30min positive / 5min negative) in front of the 9-req/min rate limiter - uTLS Cloudflare path now pools one HTTP/2 connection per host with a shared TLS session cache instead of a full handshake per request Deezer artist track-count N+1 kept: counts feed the discography download UI and are already amortized by the artist TTL cache.
This commit is contained in:
@@ -1269,6 +1269,10 @@ func (c *DeezerClient) getJSON(ctx context.Context, endpoint string, dst any) er
|
||||
for attempt := 0; attempt <= deezerMaxRetries; attempt++ {
|
||||
if attempt > 0 {
|
||||
delay := deezerRetryDelay * time.Duration(1<<(attempt-1))
|
||||
var apiErr *deezerAPIError
|
||||
if errors.As(lastErr, &apiErr) && apiErr.RetryAfter > 0 {
|
||||
delay = apiErr.RetryAfter
|
||||
}
|
||||
GoLog("[Deezer] Retry %d/%d after %v...\n", attempt, deezerMaxRetries, delay)
|
||||
time.Sleep(delay)
|
||||
}
|
||||
@@ -1292,6 +1296,7 @@ func (c *DeezerClient) getJSON(ctx context.Context, endpoint string, dst any) er
|
||||
type deezerAPIError struct {
|
||||
StatusCode int
|
||||
Body string
|
||||
RetryAfter time.Duration
|
||||
}
|
||||
|
||||
func (e *deezerAPIError) Error() string {
|
||||
@@ -1329,7 +1334,7 @@ func (c *DeezerClient) doGetJSON(ctx context.Context, endpoint string, dst any)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return &deezerAPIError{StatusCode: resp.StatusCode, Body: string(body)}
|
||||
return &deezerAPIError{StatusCode: resp.StatusCode, Body: string(body), RetryAfter: getRetryAfterDuration(resp)}
|
||||
}
|
||||
|
||||
return json.Unmarshal(body, dst)
|
||||
|
||||
Reference in New Issue
Block a user