sylvia_iot_broker/models/memory/
network_route.rs1use std::{error::Error as StdError, num::NonZeroUsize, sync::Arc};
2
3use async_trait::async_trait;
4use lru::LruCache;
5use tokio::sync::RwLock;
6
7use super::super::{
8 network_route::{ListOptions, ListQueryCond, NetworkRouteCache, NetworkRouteCacheUlData},
9 Model,
10};
11
12pub struct Cache {
13 model: Arc<dyn Model>,
14 uldata: Arc<RwLock<LruCache<String, Option<NetworkRouteCacheUlData>>>>,
15}
16
17pub struct Options {
18 pub uldata_size: usize,
19}
20
21const DEF_SIZE: usize = 10_000;
22
23impl Cache {
24 pub fn new(opts: &Options, model: Arc<dyn Model>) -> Self {
25 let uldata = unsafe { NonZeroUsize::new_unchecked(opts.uldata_size) };
26 Cache {
27 model,
28 uldata: Arc::new(RwLock::new(LruCache::new(uldata))),
29 }
30 }
31}
32
33#[async_trait]
34impl NetworkRouteCache for Cache {
35 async fn clear(&self) -> Result<(), Box<dyn StdError>> {
36 let mut lock = self.uldata.write().await;
37 lock.clear();
38 Ok(())
39 }
40
41 async fn get_uldata(
42 &self,
43 network_id: &str,
44 ) -> Result<Option<NetworkRouteCacheUlData>, Box<dyn StdError>> {
45 {
46 let mut lock = self.uldata.write().await;
47 if let Some(value) = lock.get(network_id) {
48 match value {
49 None => return Ok(None),
50 Some(value) => return Ok(Some(value.clone())),
51 }
52 }
53 }
54
55 let opts = ListOptions {
56 cond: &ListQueryCond {
57 network_id: Some(network_id),
58 ..Default::default()
59 },
60 offset: None,
61 limit: None,
62 sort: None,
63 cursor_max: None,
64 };
65 let (routes, _) = self.model.network_route().list(&opts, None).await?;
66 let data = match routes.len() {
67 0 => None,
68 _ => {
69 let mut routes_data = vec![];
70 for r in routes.iter() {
71 routes_data.push(format!("{}.{}", r.unit_code, r.application_code))
72 }
73 Some(NetworkRouteCacheUlData {
74 app_mgr_keys: routes_data,
75 })
76 }
77 };
78 let _ = self.set_uldata(network_id, data.as_ref()).await;
79 Ok(data)
80 }
81
82 async fn set_uldata(
83 &self,
84 network_id: &str,
85 value: Option<&NetworkRouteCacheUlData>,
86 ) -> Result<(), Box<dyn StdError>> {
87 let key = network_id.to_string();
88 let mut lock = self.uldata.write().await;
89 let _ = match value {
90 None => lock.push(key, None),
91 Some(value) => lock.push(key, Some(value.clone())),
92 };
93 Ok(())
94 }
95
96 async fn del_uldata(&self, network_id: &str) -> Result<(), Box<dyn StdError>> {
97 let mut lock = self.uldata.write().await;
98 lock.pop(network_id);
99 Ok(())
100 }
101}
102
103impl Default for Options {
104 fn default() -> Self {
105 Options {
106 uldata_size: DEF_SIZE,
107 }
108 }
109}