deltalake_catalog_unity/client/
token.rs1use std::future::Future;
3use std::time::Instant;
4
5use tokio::sync::Mutex;
6
7#[derive(Debug, Clone)]
9pub struct TemporaryToken<T> {
10 pub token: T,
12 pub expiry: Option<Instant>,
15}
16
17#[derive(Debug)]
20pub struct TokenCache<T> {
21 cache: Mutex<Option<TemporaryToken<T>>>,
22}
23
24impl<T> Default for TokenCache<T> {
25 fn default() -> Self {
26 Self {
27 cache: Default::default(),
28 }
29 }
30}
31
32impl<T: Clone + Send> TokenCache<T> {
33 pub async fn get_or_insert_with<F, Fut, E>(&self, f: F) -> Result<T, E>
35 where
36 F: FnOnce() -> Fut + Send,
37 Fut: Future<Output = Result<TemporaryToken<T>, E>> + Send,
38 {
39 let now = Instant::now();
40 let mut locked = self.cache.lock().await;
41
42 if let Some(cached) = locked.as_ref() {
43 match cached.expiry {
44 Some(ttl)
45 if ttl
46 .checked_duration_since(now)
47 .unwrap_or_default()
48 .as_secs()
49 > 300 =>
50 {
51 return Ok(cached.token.clone());
52 }
53 None => return Ok(cached.token.clone()),
54 _ => (),
55 }
56 }
57
58 let cached = f().await?;
59 let token = cached.token.clone();
60 *locked = Some(cached);
61
62 Ok(token)
63 }
64}