Finding
TvdbProvider calls self.bearer_token().await? at the top of both search() and get_metadata(). bearer_token() unconditionally POSTs to {BASE_URL}/login with the API key to obtain a fresh JWT, with no token caching. TVDB JWTs remain valid for 30 days after issuance, so every TVDB query issues a redundant login round-trip.
Evidence
crates/epignosis/src/providers/tvdb.rs:98:
let token = self.bearer_token().await?;
The same pattern appears at crates/epignosis/src/providers/tvdb.rs:141 in get_metadata(). The TvdbProvider struct holds no token-storage field, so the JWT is never retained between calls.
Why this matters
Each TVDB operation consumes 2 of the 10 req/s rate-limit budget (1 login + 1 actual call), halving effective throughput. During a batch enrichment run the login endpoint can itself become rate-limited, surfacing as intermittent ProviderRequestSnafu failures that read as "TVDB is down" rather than a client-side defect. Two concurrent TVDB queries each log in independently, compounding the redundancy. Under a network-observing adversary the doubled login traffic also doubles the observable request footprint per query, leaking more about device activity than necessary.
Desired correction
Cache the token and its expiry on TvdbProvider (e.g. Arc<tokio::sync::RwLock<Option<(String, Instant)>>>). On each call, reuse the cached token while it is still valid (e.g. issued within the last 24 hours) and POST to /login only when the token is absent or expired. Done when: 100 consecutive TVDB searches result in exactly 1 login request.
Finding
TvdbProvidercallsself.bearer_token().await?at the top of bothsearch()andget_metadata().bearer_token()unconditionally POSTs to{BASE_URL}/loginwith the API key to obtain a fresh JWT, with no token caching. TVDB JWTs remain valid for 30 days after issuance, so every TVDB query issues a redundant login round-trip.Evidence
crates/epignosis/src/providers/tvdb.rs:98:The same pattern appears at
crates/epignosis/src/providers/tvdb.rs:141inget_metadata(). TheTvdbProviderstruct holds no token-storage field, so the JWT is never retained between calls.Why this matters
Each TVDB operation consumes 2 of the 10 req/s rate-limit budget (1 login + 1 actual call), halving effective throughput. During a batch enrichment run the login endpoint can itself become rate-limited, surfacing as intermittent
ProviderRequestSnafufailures that read as "TVDB is down" rather than a client-side defect. Two concurrent TVDB queries each log in independently, compounding the redundancy. Under a network-observing adversary the doubled login traffic also doubles the observable request footprint per query, leaking more about device activity than necessary.Desired correction
Cache the token and its expiry on
TvdbProvider(e.g.Arc<tokio::sync::RwLock<Option<(String, Instant)>>>). On each call, reuse the cached token while it is still valid (e.g. issued within the last 24 hours) and POST to/loginonly when the token is absent or expired. Done when: 100 consecutive TVDB searches result in exactly 1 login request.