adk_auth/secrets/
cached.rs1use std::collections::HashMap;
7use std::sync::Arc;
8use std::time::{Duration, Instant};
9
10use adk_core::AdkError;
11use async_trait::async_trait;
12use tokio::sync::RwLock;
13
14use super::provider::SecretProvider;
15
16struct CachedEntry {
18 value: String,
19 expires_at: Instant,
20}
21
22pub struct CachedSecretProvider<P: SecretProvider> {
37 inner: P,
38 cache: Arc<RwLock<HashMap<String, CachedEntry>>>,
39 ttl: Duration,
40}
41
42impl<P: SecretProvider> CachedSecretProvider<P> {
43 pub fn new(inner: P, ttl: Duration) -> Self {
45 Self { inner, cache: Arc::new(RwLock::new(HashMap::new())), ttl }
46 }
47}
48
49#[async_trait]
50impl<P: SecretProvider> SecretProvider for CachedSecretProvider<P> {
51 async fn get_secret(&self, name: &str) -> Result<String, AdkError> {
52 {
54 let cache = self.cache.read().await;
55 if let Some(entry) = cache.get(name) {
56 if entry.expires_at > Instant::now() {
57 return Ok(entry.value.clone());
58 }
59 }
60 }
61
62 let value = self.inner.get_secret(name).await?;
64
65 {
67 let mut cache = self.cache.write().await;
68 cache.insert(
69 name.to_string(),
70 CachedEntry { value: value.clone(), expires_at: Instant::now() + self.ttl },
71 );
72 }
73
74 Ok(value)
75 }
76}