diff --git a/crates/oidc-provider/src/cache.rs b/crates/oidc-provider/src/cache.rs index 9ef156a..e684f52 100644 --- a/crates/oidc-provider/src/cache.rs +++ b/crates/oidc-provider/src/cache.rs @@ -16,21 +16,22 @@ use crate::BackendCredentials; const EXPIRY_MARGIN_SECS: i64 = 60; /// Thread-safe TTL cache for cloud credentials. +/// +/// `Clone` shares the same underlying store (the entries map is behind an +/// `Arc`), so a cloned [`OidcCredentialProvider`](crate::OidcCredentialProvider) +/// keeps hitting the same cache — letting a runtime hold the provider in a +/// shared/`static` slot and reuse it across requests instead of re-minting and +/// re-exchanging every time. +#[derive(Clone, Default)] pub struct CredentialCache { - entries: Mutex>>, -} - -impl Default for CredentialCache { - fn default() -> Self { - Self::new() - } + entries: Arc>>>, } impl CredentialCache { /// Create an empty credential cache. pub fn new() -> Self { Self { - entries: Mutex::new(HashMap::new()), + entries: Arc::new(Mutex::new(HashMap::new())), } } diff --git a/crates/oidc-provider/src/lib.rs b/crates/oidc-provider/src/lib.rs index 18d642d..a383a00 100644 --- a/crates/oidc-provider/src/lib.rs +++ b/crates/oidc-provider/src/lib.rs @@ -56,6 +56,11 @@ pub trait HttpExchange: } /// Top-level provider that combines signing, exchange, and caching. +/// +/// `Clone` is cheap and shares the credential cache (and the `Clone` HTTP +/// client), so a runtime can construct one provider and reuse it across requests +/// — keeping the cache warm instead of re-minting + re-exchanging every call. +#[derive(Clone)] pub struct OidcCredentialProvider { signer: JwtSigner, cache: CredentialCache,