Problem
Every call to connector.connect(url) makes a network round-trip to the auth server to obtain a new token, even when the previous token is still valid. This adds unnecessary latency (and can trigger auth-server rate limits) in patterns like:
// Each call hits the auth server unnecessarily
let api = connector.connect(url).await?;
// ... later in a retry or reconnect path:
let api = connector.connect(url).await?;
Proposed feature
Add in-memory token caching in the Authorization trait implementations generated by the proc macros. Cache the token alongside its expiry, and reuse it until it is close to expiring.
Proposed design
Introduce a TokenCache struct:
pub struct TokenCache {
token: Option<(AuthorizationType, DateTime<Utc>)>,
refresh_before_expiry: Duration, // default: 30s
}
The generated connect() code checks the cache before making an HTTP request:
async fn connect(&self, url: &str) -> Result<Api<...>> {
if let Some(valid_token) = self.cache.get_valid() {
return Ok(ApiBuilder::new(url).bearer(valid_token).build());
}
// ... perform auth request, store result in cache
}
Token expiry
OAuth2/OIDC token responses include expires_in (seconds). Parse and store this alongside the token. Treat tokens without expires_in as session-lived (no caching).
Thread safety
TokenCache should be wrapped in Arc<RwLock<>> in the connector struct so it is safe to share across tasks.
Opt-out
Caching should be opt-in via a #[token_cache] attribute on the connector struct, or opt-out via #[token_cache(disabled)], to keep existing behaviour unchanged.
Related
- Automatic token refresh issue
Problem
Every call to
connector.connect(url)makes a network round-trip to the auth server to obtain a new token, even when the previous token is still valid. This adds unnecessary latency (and can trigger auth-server rate limits) in patterns like:Proposed feature
Add in-memory token caching in the
Authorizationtrait implementations generated by the proc macros. Cache the token alongside its expiry, and reuse it until it is close to expiring.Proposed design
Introduce a
TokenCachestruct:The generated
connect()code checks the cache before making an HTTP request:Token expiry
OAuth2/OIDC token responses include
expires_in(seconds). Parse and store this alongside the token. Treat tokens withoutexpires_inas session-lived (no caching).Thread safety
TokenCacheshould be wrapped inArc<RwLock<>>in the connector struct so it is safe to share across tasks.Opt-out
Caching should be opt-in via a
#[token_cache]attribute on the connector struct, or opt-out via#[token_cache(disabled)], to keep existing behaviour unchanged.Related