Skip to content

Feature: token caching — reuse unexpired tokens across connect() calls #57

Description

@ZialeHub

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    B-ideaDiscussion; or implementation attempt, to be reviewed before further workrustPull requests that update rust code

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions