cal-redis 0.1.80

Callable Redis Implementation
Documentation
// File: cal-redis/src/cache/device.rs

use crate::cache::CallableCache;
use crate::{get_device, get_device_by_ident, get_devices};
use cal_core::device::device::DeviceStruct;
use redis::RedisError;
use std::sync::Arc;

impl CallableCache {
    pub async fn get_device_by_ident(
        self,
        account_id: &str,
        ident: &str,
    ) -> Result<Option<Arc<DeviceStruct>>, RedisError> {
        println!("[CallableCache::get_device_by_ident] Looking up device - Account: {}, Ident: {}", account_id, ident);
        // Create a composite key for the account-device_ident combination
        let key = format!("{}:{}", account_id, ident);

        // Try to get the Device ID from the local ddi-device cache
        if let Some(device_id) = self.local_cache.device_idents.get(&key) {
            println!("[CallableCache::get_device_by_ident] Found device_id in local cache: {}", device_id);
            // If we have a device ID, try to get device  from the local device cache
            if let Some(device) = self.local_cache.devices.get(device_id.as_str()) {
                println!("[CallableCache::get_device_by_ident] Found device in local cache");
                self.local_cache.devices.insert(device_id, device.clone());
                return Ok(Some(device));
            }

            // If device not in local cache, but we have the ID, fetch from Redis
            println!("[CallableCache::get_device_by_ident] Device not in local cache, fetching from Redis");
            match get_device(
                self.remote_cache.connection.clone(),
                account_id,
                device_id.as_str(),
            )
                .await?
            {
                Some(device) => {
                    println!("[CallableCache::get_device_by_ident] Found device in Redis: {}", device.name);
                    // Cache the retrieved device ident for future use
                    self.local_cache
                        .devices
                        .insert(device_id, Arc::new(device.clone()));
                    self.local_cache
                        .device_idents
                        .insert(ident.to_string(), device.id.clone());
                    Ok(Some(Arc::new(device)))
                }
                None => {
                    println!("[CallableCache::get_device_by_ident] Device not found in Redis");
                    Ok(None)
                }
            }
        } else {
            // If account-device_ident combination not in local cache, try Redis
            println!("[CallableCache::get_device_by_ident] Device ident not in local cache, checking Redis");
            match get_device_by_ident(self.remote_cache.connection.clone(), account_id, ident)
                .await?
            {
                Some(device) => {
                    println!("[CallableCache::get_device_by_ident] Found device in Redis by ident: {}", device.name);
                    // Cache the retrieved account for future use
                    self.local_cache
                        .devices
                        .insert(device.id.clone(), Arc::new(device.clone()));
                    self.local_cache
                        .device_idents
                        .insert(device.id.clone().to_string(), device.id.clone());
                    Ok(Some(Arc::new(device)))
                }
                None => {
                    println!("[CallableCache::get_device_by_ident] No device found for ident");
                    Ok(None)
                }
            }
        }
    }

    /// Retrieves all devices for an account.
    ///
    /// # Arguments
    /// * `account_id` - Account ID
    ///
    /// # Returns
    /// * `Result<Vec<DeviceStruct>, RedisError>` - List of devices or a Redis error
    pub async fn get_devices(self, account_id: &str) -> Result<Arc<Vec<DeviceStruct>>, RedisError> {
        println!("[CallableCache::get_devices] Getting all devices for account: {}", account_id);
        // Get from Redis and update local cache
        let devices = get_devices(self.remote_cache.connection.clone(), account_id).await?;
        println!("[CallableCache::get_devices] Retrieved {} devices from Redis", devices.len());

        // Cache each device locally for future use
        for device in &devices {
            let cache_key = format!("{}:{}", account_id, device.id);
            println!("[CallableCache::get_devices] Caching device: {} with key: {}", device.name, cache_key);
            self.local_cache
                .devices
                .insert(cache_key, Arc::new(device.clone()));
        }

        Ok(Arc::new(devices))
    }

    /// Retrieves a specific device for an account.
    ///
    /// # Arguments
    /// * `account_id` - Account ID
    /// * `device_id` - Device ID to retrieve
    ///
    /// # Returns
    /// * `Result<Option<DeviceStruct>, RedisError>` - The device if found, None if not found, or a Redis error
    pub async fn get_device(
        self,
        account_id: &str,
        device_id: &str,
    ) -> Result<Option<Arc<DeviceStruct>>, RedisError> {
        println!("[CallableCache::get_device] Getting device - Account: {}, Device ID: {}", account_id, device_id);
        // Try local cache first
        let cache_key = format!("{}:{}", account_id, device_id);
        if let Some(device) = self.local_cache.devices.get(&cache_key) {
            println!("[CallableCache::get_device] Found device in local cache");
            return Ok(Some(device));
        }

        // If not in local cache, try Redis
        println!("[CallableCache::get_device] Device not in local cache, fetching from Redis");
        match get_device(self.remote_cache.connection.clone(), account_id, device_id).await? {
            Some(device) => {
                println!("[CallableCache::get_device] Found device in Redis: {}", device.name);
                // Cache for future use
                self.local_cache
                    .devices
                    .insert(cache_key, Arc::new(device.clone()));
                Ok(Some(Arc::new(device)))
            }
            None => {
                println!("[CallableCache::get_device] Device not found in Redis");
                Ok(None)
            }
        }
    }
}