unleash-edge 8.0.1

Unleash edge is a proxy for Unleash. It can return both evaluated feature toggles as well as the raw data from Unleash's client API
Documentation
use std::{collections::HashMap, sync::Arc, time::Duration};

use async_trait::async_trait;
use dashmap::DashMap;
use tracing::{debug, warn};
use unleash_types::client_features::ClientFeatures;

use crate::types::{EdgeResult, EdgeToken, TokenRefresh, TokenValidationStatus};

pub mod file;
pub mod redis;

#[async_trait]
pub trait EdgePersistence: Send + Sync {
    async fn load_tokens(&self) -> EdgeResult<Vec<EdgeToken>>;
    async fn save_tokens(&self, tokens: Vec<EdgeToken>) -> EdgeResult<()>;
    async fn load_refresh_targets(&self) -> EdgeResult<Vec<TokenRefresh>>;
    async fn save_refresh_targets(&self, refresh_targets: Vec<TokenRefresh>) -> EdgeResult<()>;
    async fn load_features(&self) -> EdgeResult<HashMap<String, ClientFeatures>>;
    async fn save_features(&self, features: Vec<(String, ClientFeatures)>) -> EdgeResult<()>;
}

#[cfg(not(tarpaulin_include))]
pub async fn persist_data(
    persistence: Option<Arc<dyn EdgePersistence>>,
    token_cache: Arc<DashMap<String, EdgeToken>>,
    features_cache: Arc<DashMap<String, ClientFeatures>>,
    refresh_targets_cache: Arc<DashMap<String, TokenRefresh>>,
) {
    loop {
        tokio::select! {
            _ = tokio::time::sleep(Duration::from_secs(60)) => {
                if let Some(persister) = persistence.clone() {
                    if persister.save_tokens(token_cache.iter().filter(|t| t.value().status == TokenValidationStatus::Validated).map(|e| e.value().clone()).collect()).await.is_ok() {
                        debug!("Persisted tokens");
                    } else {
                        warn!("Could not persist tokens");
                    }
                    if persister.save_features(features_cache.iter().map(|e| (e.key().clone(), e.value().clone())).collect()).await.is_ok() {
                        debug!("Persisted features");
                    } else {
                        warn!("Could not persist features");
                    }

                    if persister.save_refresh_targets(refresh_targets_cache.iter().map(|e| e.value().clone()).collect()).await.is_ok() {
                        debug!("Persisted refresh targets");
                    } else {
                        warn!("Could not persist refresh targets");
                    }
                } else {
                    debug!("Had no persister. Nothing was persisted");
                }
            }
        }
    }
}