cal_redis/
local_cache.rs

1use cal_core::device::device::DeviceStruct;
2use cal_core::{AccountLite, Asset, FlowState, Hook, Proxy, Region, Trunk, User, UserLite, DDI};
3use moka::sync::Cache;
4use std::sync::Arc;
5use std::time::Duration;
6
7
8/// In-memory cache for storing frequently accessed data.
9///
10/// Uses Moka cache for efficient memory usage with TTL-based expiration.
11/// Now supports shared references via `Arc` for complex types like `FlowState`.
12#[derive(Clone)]
13pub struct LocalCache {
14    /// Cache for proxy objects
15    pub proxies: Cache<String, Arc<Proxy>>,
16    /// Cache for flow state objects (shared via Arc, longer TTL)
17    pub flow_state: Cache<String, Arc<FlowState>>,
18    /// Cache for region objects
19    pub regions: Cache<String, Arc<Region>>,
20    /// Cache for region identifier mappings
21    pub region_idents: Cache<String, String>,
22    /// Cache for account objects
23    pub accounts: Cache<String, Arc<AccountLite>>,
24    /// Cache for account identifier mappings
25    pub account_idents: Cache<String, String>,
26    /// Cache for device objects
27    pub devices: Cache<String, Arc<DeviceStruct>>,
28    /// Cache for trunk objects
29    pub trunks: Cache<String, Trunk>,
30    /// Cache for DDI objects
31    pub ddis: Cache<String, DDI>,
32    /// Cache for hook objects
33    pub hooks: Cache<String, Hook>,
34    /// Cache for asset objects
35    pub assets: Cache<String, Asset>,
36    /// Cache for trunk_ddi identifier mappings
37    pub trunk_ddi_idents: Cache<String, String>,
38    /// Cache for ddi_device identifier mappings
39    pub device_idents: Cache<String, String>,
40    /// Cache for user objects
41    pub users: Cache<String, Arc<User>>,
42    /// Cache for user identifier mappings
43    pub user_idents: Cache<String, String>,
44}
45
46/// Helper function to build a cache with specific capacity and TTL.
47fn create_cache<T: Clone + Send + Sync + 'static>(capacity_mb: u64, ttl_secs: u64) -> Cache<String, T> {
48    Cache::builder()
49        .max_capacity(capacity_mb * 1024 * 1024)
50        .time_to_live(Duration::from_secs(ttl_secs))
51        .build()
52}
53
54/// Builds the full local cache with default parameters.
55/// Includes Arc support for `FlowState`.
56pub fn build_local_cache() -> LocalCache {
57    LocalCache {
58        flow_state: create_cache::<Arc<FlowState>>(50, 60 * 60 * 4),
59        regions: create_cache::<Arc<Region>>(5, 60),
60        accounts: create_cache::<Arc<AccountLite>>(50, 60),
61        devices: create_cache::<Arc<DeviceStruct>>(20, 60),
62        trunks: create_cache::<Trunk>(10, 60),
63        ddis: create_cache::<DDI>(10, 60),
64        hooks: create_cache::<Hook>(10, 60),
65        assets: create_cache::<Asset>(10, 60),
66        proxies: create_cache::<Arc<Proxy>>(10, 60 * 60),
67        region_idents: create_cache::<String>(5, 60),
68        account_idents: create_cache::<String>(5, 60),
69        trunk_ddi_idents: create_cache::<String>(10, 60),
70        device_idents: create_cache::<String>(10, 60),
71        users: create_cache::<Arc<User>>(20, 60),
72        user_idents: create_cache::<String>(5, 60),
73    }
74}
75
76/// Builds and stores region identifier mappings in the local cache.
77///
78/// # Arguments
79/// * `reg` - Region to store locally
80///
81/// # Returns
82/// * `()` - This function doesn't fail
83pub fn build_region_identifiers_locally(local_cache: LocalCache, reg: Arc<Region>) {
84    // Store the region in local cache
85    local_cache.regions.insert(reg.id.to_string(), reg.clone());
86
87    // Add primary identifier
88    local_cache.region_idents.insert(reg.id.to_string(), reg.id.to_string());
89
90    // Add alternative identifiers
91    for vs in &reg.voice_servers {
92        local_cache.region_idents.insert(vs.id.to_string(), reg.id.to_string());
93        local_cache.region_idents.insert(vs.public_ip.to_string(), reg.id.to_string());
94        local_cache.region_idents.insert(vs.private_ip.to_string(), reg.id.to_string());
95    }
96}
97
98/// Populates the local account cache with account identifiers.
99///
100/// # Arguments
101/// * `acc` - Account to cache locally
102///
103/// # Returns
104/// * `()` - This function doesn't fail
105pub fn build_account_identifiers_locally(local_cache: LocalCache, acc: &AccountLite) {
106
107    println!("Building account identifiers for {}", acc.id);
108
109    // Store the account in local cache
110    local_cache.accounts.insert(acc.id.clone(), Arc::new(acc.clone()));
111
112    // Add primary identifier to local cache
113    local_cache.account_idents.insert(acc.id.clone(), acc.id.clone());
114
115    // Add domain-based identifiers to local cache
116    local_cache.account_idents.insert(
117        format!("{}.connect.callable.io", acc.domain),
118        acc.id.clone(),
119    );
120
121    // Add teams identifiers to local cache
122    if !acc.teams.domain.is_empty() {
123        local_cache.account_idents.insert(
124            format!("{}.teams.callable.io", acc.teams.domain),
125            acc.id.clone(),
126        );
127    }
128}
129
130
131
132// Add this function to local_cache.rs
133pub fn build_user_identifiers_locally(local_cache: &LocalCache, user: &User) {
134    println!("Building user identifiers for {}", user.id);
135
136    // Store the user in local cache
137    local_cache.users.insert(user.id.clone(), Arc::new(user.clone()));
138
139    // Add primary identifier to local cache
140    local_cache.user_idents.insert(user.id.clone(), user.id.clone());
141
142    // Add email identifier to local cache
143    local_cache.user_idents.insert(user.email.clone(), user.id.clone());
144}
145