| 155 | #[async_trait] |
| 156 | impl SecretsReader for CachingSecretsReader { |
| 157 | async fn read(&self, id: CatalogItemId) -> Result<Vec<u8>, anyhow::Error> { |
| 158 | // Iff our cache is enabled will we read from it. |
| 159 | if self.policy.enabled() { |
| 160 | let read_guard = self.cache.read().expect("CachingSecretsReader panicked!"); |
| 161 | let ttl = self.policy.ttl(); |
| 162 | |
| 163 | // If we have a cached value we still need to check if it's expired. |
| 164 | if let Some(CacheItem { secret, ts }) = read_guard.get(&id) { |
| 165 | if Instant::now().duration_since(*ts) < ttl { |
| 166 | return Ok(secret.clone()); |
| 167 | } |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | // Otherwise, we need to read from source! |
| 172 | let value = self.inner.read(id).await?; |
| 173 | |
| 174 | // Cache it, if caching is enabled. |
| 175 | if self.policy.enabled() { |
| 176 | let cache_value = CacheItem::new(value.clone(), Instant::now()); |
| 177 | self.cache |
| 178 | .write() |
| 179 | .expect("CachingSecretsReader panicked!") |
| 180 | .insert(id, cache_value); |
| 181 | } |
| 182 | |
| 183 | Ok(value) |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | #[cfg(test)] |