1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// File: cal-redis/src/cache/region.rs
use super::CallableCache;
use crate::local_cache::build_region_identifiers_locally;
use crate::{get_region_by_ident, get_regions};
use cal_core::Region;
use redis::RedisError;
use std::sync::Arc;
impl CallableCache {
/// Retrieves a region by its ID, first checking the local cache and then Redis.
///
/// # Arguments
/// * `id` - Region ID to look up
///
/// # Returns
/// * `Result<Option<Region>, RedisError>` - Region if found, None if not found, or a Redis error
pub async fn get_region_by_id(self, id: &str) -> Result<Option<Arc<Region>>, RedisError> {
println!("CallableCache: get_region_by_id, Getting by ident: {}", id);
// Try to get the resolved ID from the local cache
if let Some(resolved_id) = self.local_cache.region_idents.get(id) {
// If we have a resolved ID, try to get the region from the local cache
println!(
"CallableCache: get_region_by_id, Got local region_ident: {}",
resolved_id
);
if let Some(region) = self.local_cache.regions.get(resolved_id.as_str()) {
println!(
"CallableCache: get_region_by_id, Got local region: {}",
resolved_id
);
return Ok(Some(region));
}
// If not in local cache, fetch from Redis using the resolved ID
match get_region_by_ident(self.remote_cache.connection.clone(), &resolved_id).await? {
Some(region) => {
println!(
"CallableCache: get_region_by_id, Got remote Region {}",
region.id
);
// Cache the retrieved region for future use
self.local_cache
.region_idents
.insert(id.to_string(), region.id.to_string());
build_region_identifiers_locally(self.local_cache, Arc::new(region.clone()));
Ok(Some(Arc::new(region)))
}
None => {
println!(
"CallableCache: get_region_by_id, No remote Region {}",
resolved_id
);
Ok(None)
}
}
} else {
// If region identifier not in local cache, try Redis
println!(
"CallableCache: get_region_by_id, No local region, checking remote {}",
id
);
match get_region_by_ident(self.remote_cache.connection.clone(), id).await? {
Some(region) => {
// Cache the retrieved region for future use
println!(
"CallableCache: get_region_by_id, Found remote region {}",
region.id
);
self.local_cache
.region_idents
.insert(id.to_string(), region.id.to_string());
build_region_identifiers_locally(self.local_cache, Arc::new(region.clone()));
Ok(Some(Arc::new(region)))
}
None => {
println!(
"CallableCache: get_region_by_id, no local or remote region! {}",
id
);
Ok(None)
}
}
}
}
/// Retrieves all regions from Local.
///
/// # Returns
/// * `Result<Vec<Region>, RedisError>` - Arc Vec of Regions
pub async fn get_regions_local(self) -> Result<Arc<Vec<Region>>, RedisError> {
println!("[CallableCache::get_regions_local] Getting regions from local cache");
// Collect the Arc<Region> values and map them into a Vec<Region> (no cloning of Region data)
let regions: Vec<Region> = self
.local_cache
.regions
.iter()
.map(|(_, value)| (*value).clone()) // Dereference the Arc and clone the inner Region
.collect();
println!("[CallableCache::get_regions_local] Found {} regions in local cache", regions.len());
// Wrap the Vec<Region> in an Arc
Ok(Arc::new(regions))
}
/// Retrieves all regions from Redis.
///
/// # Returns
/// * `Result<Vec<Region>, RedisError>` - Vec of Regions
pub async fn get_regions(self) -> Result<Arc<Vec<Region>>, RedisError> {
println!("[CallableCache::get_regions] Getting all regions from Redis");
let regions = get_regions(self.remote_cache.connection).await?;
println!("[CallableCache::get_regions] Retrieved {} regions from Redis", regions.len());
for region in ®ions {
build_region_identifiers_locally(self.local_cache.clone(), Arc::new(region.clone()));
}
Ok(Arc::new(regions))
}
}