tako_rs_plugins/middleware/session/
data.rs1use std::sync::Arc;
4use std::sync::atomic::AtomicBool;
5use std::sync::atomic::AtomicU64;
6use std::sync::atomic::Ordering;
7
8use parking_lot::Mutex;
9use serde::Serialize;
10use serde::de::DeserializeOwned;
11
12#[derive(Clone)]
14pub struct Session {
15 data: Arc<Mutex<serde_json::Map<String, serde_json::Value>>>,
16 dirty: Arc<AtomicBool>,
17 rotation_counter: Arc<AtomicU64>,
18 destroyed: Arc<AtomicBool>,
19}
20
21impl Session {
22 pub(crate) fn new(data: serde_json::Map<String, serde_json::Value>) -> Self {
23 Self {
24 data: Arc::new(Mutex::new(data)),
25 dirty: Arc::new(AtomicBool::new(false)),
26 rotation_counter: Arc::new(AtomicU64::new(0)),
27 destroyed: Arc::new(AtomicBool::new(false)),
28 }
29 }
30
31 pub fn get<T: DeserializeOwned>(&self, key: &str) -> Option<T> {
33 self
34 .data
35 .lock()
36 .get(key)
37 .and_then(|v| serde_json::from_value(v.clone()).ok())
38 }
39
40 pub fn set<T: Serialize>(&self, key: &str, value: T) {
42 if let Ok(v) = serde_json::to_value(value) {
43 self.data.lock().insert(key.to_string(), v);
44 self.dirty.store(true, Ordering::Relaxed);
45 }
46 }
47
48 pub fn remove(&self, key: &str) {
50 if self.data.lock().remove(key).is_some() {
51 self.dirty.store(true, Ordering::Relaxed);
52 }
53 }
54
55 pub fn clear(&self) {
60 let mut guard = self.data.lock();
61 if !guard.is_empty() {
62 guard.clear();
63 self.dirty.store(true, Ordering::Relaxed);
64 }
65 }
66
67 pub fn destroy(&self) {
72 self.data.lock().clear();
73 self.destroyed.store(true, Ordering::Release);
74 self.dirty.store(true, Ordering::Relaxed);
75 }
76
77 pub(crate) fn is_destroyed(&self) -> bool {
78 self.destroyed.load(Ordering::Acquire)
79 }
80
81 pub fn rotate(&self) {
85 self.rotation_counter.fetch_add(1, Ordering::AcqRel);
86 self.dirty.store(true, Ordering::Relaxed);
87 }
88
89 pub(crate) fn is_dirty(&self) -> bool {
90 self.dirty.load(Ordering::Relaxed)
91 }
92
93 pub fn rotation_requested(&self) -> bool {
98 self.rotation_counter.load(Ordering::Acquire) > 0
99 }
100
101 pub(crate) fn snapshot(&self) -> serde_json::Map<String, serde_json::Value> {
102 self.data.lock().clone()
103 }
104}