Skip to content
Clone
b453d5d
104 lines 2.3 KB Rust
use std::time::Duration;
use cache::CacheClient;
use serde::{Serialize, de::DeserializeOwned};
use crate::share::errors::GitError;
pub const REV_TTL: Duration = Duration::from_secs(60);
pub const ANALYSIS_TTL: Duration = Duration::from_secs(600);
pub const IMMUTABLE_TTL: Duration = Duration::from_secs(30 * 24 * 3600);
pub fn sanitize_key(k: &str) -> String {
let mut out = String::with_capacity(k.len());
for c in k.chars() {
if c.is_ascii_alphanumeric() || matches!(c, '-' | '_' | '.' | ':' | '/') {
out.push(c);
} else {
out.push('_');
}
}
out
}
pub async fn cached_fetch<V, F, Fut>(
cache: &CacheClient,
key: &str,
ttl: Duration,
fetch: F,
) -> Result<V, GitError>
where
V: Serialize + DeserializeOwned,
F: FnOnce() -> Fut,
Fut: std::future::Future<Output = Result<V, GitError>>,
{
let sanitized = sanitize_key(key);
if let Ok(Some(cached)) = cache.get::<V>(&sanitized).await {
return Ok(cached);
}
let val = fetch().await?;
let _ = cache.set(&sanitized, &val, Some(ttl)).await;
Ok(val)
}
fn oid_key(kind: &str, oid: &str) -> String {
sanitize_key(&format!("object.{kind}.{oid}"))
}
fn rev_key(module: &str, func: &str, key_part: &str, tip: &str) -> String {
sanitize_key(&format!("{module}.{func}.{key_part}:{tip}"))
}
pub async fn cache_oid_get<V>(
cache: &CacheClient,
kind: &str,
oid: &str,
) -> Result<Option<V>, GitError>
where
V: DeserializeOwned,
{
Ok(cache.get(&oid_key(kind, oid)).await?)
}
pub async fn cache_oid_put<V>(
cache: &CacheClient,
kind: &str,
oid: &str,
v: &V,
) -> Result<(), GitError>
where
V: Serialize,
{
cache.set(&oid_key(kind, oid), v, None).await?;
Ok(())
}
pub async fn cache_rev_get<V>(
cache: &CacheClient,
module: &str,
func: &str,
key_part: &str,
tip: &str,
) -> Result<Option<V>, GitError>
where
V: DeserializeOwned,
{
Ok(cache.get(&rev_key(module, func, key_part, tip)).await?)
}
pub async fn cache_rev_put<V>(
cache: &CacheClient,
module: &str,
func: &str,
key_part: &str,
tip: &str,
v: &V,
) -> Result<(), GitError>
where
V: Serialize,
{
cache
.set(&rev_key(module, func, key_part, tip), v, Some(REV_TTL))
.await?;
Ok(())
}