kevy_embedded/
store_inner.rs1use std::sync::atomic::{AtomicBool, Ordering};
7use std::sync::{Arc, Mutex, RwLock, Weak};
8use std::thread::JoinHandle;
9
10#[cfg(feature = "persist")]
11use kevy_persist::Aof;
12
13use crate::config::Config;
14use crate::pubsub::PubsubBus;
15#[cfg(feature = "persist")]
16use crate::store::lock_write;
17use crate::store::{Shards, Store};
18
19#[derive(Clone)]
25pub struct WeakStore {
26 shards: Weak<Vec<Arc<RwLock<Inner>>>>,
27 guard: Weak<DropGuard>,
28 config: Config,
29 #[cfg(all(feature = "replicate", not(target_arch = "wasm32")))]
30 feed_weak: Option<std::sync::Weak<Mutex<kevy_replicate::feed::FeedSource>>>,
31 blocker_weak: Weak<crate::ops_blocking::Blocker>,
32 #[cfg(feature = "index")]
33 indexes_weak: Weak<crate::ops_index::IndexReg>,
34 #[cfg(feature = "index")]
35 views_weak: Weak<crate::ops_view::ViewReg>,
36}
37
38impl WeakStore {
39 pub fn upgrade(&self) -> Option<Store> {
42 let guard = self.guard.upgrade()?;
43 Some(Store {
44 shards: self.shards.upgrade()?,
45 config: self.config.clone(),
46 #[cfg(all(feature = "replicate", not(target_arch = "wasm32")))]
47 feed: self.feed_weak.as_ref().and_then(std::sync::Weak::upgrade),
48 blocker: self.blocker_weak.upgrade()?,
49 #[cfg(feature = "index")]
50 indexes: self.indexes_weak.upgrade()?,
51 #[cfg(feature = "index")]
52 views: self.views_weak.upgrade()?,
53 #[cfg(feature = "index")]
54 tables: guard.tables.clone(),
55 open_report: guard.open_report.clone(),
59 guard,
60 })
61 }
62}
63
64impl Store {
65 pub fn downgrade(&self) -> WeakStore {
67 WeakStore {
68 shards: Arc::downgrade(&self.shards),
69 guard: Arc::downgrade(&self.guard),
70 config: self.config.clone(),
71 #[cfg(all(feature = "replicate", not(target_arch = "wasm32")))]
72 feed_weak: self.feed.as_ref().map(Arc::downgrade),
73 blocker_weak: Arc::downgrade(&self.blocker),
74 #[cfg(feature = "index")]
75 indexes_weak: Arc::downgrade(&self.indexes),
76 #[cfg(feature = "index")]
77 views_weak: Arc::downgrade(&self.views),
78 }
79 }
80}
81
82pub(crate) struct Inner {
83 pub(crate) store: kevy_store::Store,
84 #[cfg(feature = "persist")]
85 pub(crate) aof: Option<Aof>,
86 pub(crate) bus: PubsubBus,
89 #[cfg(all(feature = "replicate", not(target_arch = "wasm32")))]
94 pub(crate) writer_source:
95 Option<std::sync::Arc<Mutex<kevy_replicate::source::ReplicationSource>>>,
96 #[cfg(all(feature = "replicate", not(target_arch = "wasm32")))]
99 pub(crate) feed: Option<std::sync::Arc<Mutex<kevy_replicate::feed::FeedSource>>>,
100 pub(crate) blocker: Option<Arc<crate::ops_blocking::Blocker>>,
102 #[cfg(feature = "index")]
105 pub(crate) idx_segs: crate::ops_index::ShardSegs,
106 #[cfg(feature = "index")]
107 pub(crate) idx_reg: Option<Arc<crate::ops_index::IndexReg>>,
108 #[cfg(feature = "index")]
110 pub(crate) view_segs: crate::ops_view::ShardViews,
111 #[cfg(feature = "index")]
112 pub(crate) view_reg: Option<Arc<crate::ops_view::ViewReg>>,
113}
114
115impl Inner {
116 pub(crate) fn new(store: kevy_store::Store, #[cfg(feature = "persist")] aof: Option<Aof>) -> Self {
117 Inner {
118 store,
119 #[cfg(feature = "persist")]
120 aof,
121 bus: PubsubBus::new(),
122 #[cfg(all(feature = "replicate", not(target_arch = "wasm32")))]
123 writer_source: None,
124 #[cfg(all(feature = "replicate", not(target_arch = "wasm32")))]
125 feed: None,
126 blocker: None,
127 #[cfg(feature = "index")]
128 idx_segs: crate::ops_index::ShardSegs::default(),
129 #[cfg(feature = "index")]
130 idx_reg: None,
131 #[cfg(feature = "index")]
132 view_segs: crate::ops_view::ShardViews::default(),
133 #[cfg(feature = "index")]
134 view_reg: None,
135 }
136 }
137}
138
139pub(crate) struct DropGuard {
143 pub(crate) shutdown: AtomicBool,
147 pub(crate) open_report: Arc<crate::metric::OpenReport>,
152 #[cfg(feature = "index")]
156 pub(crate) tables: Arc<crate::ops_table::TableReg>,
157 pub(crate) reaper_stop: Option<Arc<AtomicBool>>,
158 pub(crate) reaper_join: Mutex<Option<JoinHandle<()>>>,
159 #[cfg_attr(not(feature = "persist"), allow(dead_code))]
162 pub(crate) shards_for_flush: Shards,
163 #[cfg(all(feature = "replicate", not(target_arch = "wasm32")))]
168 pub(crate) replica_runner: Option<crate::replica_runner::ReplicaRunner>,
169 #[cfg(all(feature = "replicate", not(target_arch = "wasm32")))]
173 pub(crate) feed_close: Option<(
174 std::sync::Arc<Mutex<kevy_replicate::feed::FeedSource>>,
175 std::path::PathBuf,
176 )>,
177 #[cfg(all(feature = "replicate", not(target_arch = "wasm32")))]
182 pub(crate) replica_source: Option<crate::replica_source::ReplicaSource>,
183}
184
185impl Drop for DropGuard {
186 fn drop(&mut self) {
187 #[cfg(all(feature = "replicate", not(target_arch = "wasm32")))]
191 if let Some(r) = &self.replica_runner {
192 r.shutdown();
193 }
194 #[cfg(all(feature = "replicate", not(target_arch = "wasm32")))]
197 if let Some(rs) = &self.replica_source {
198 rs.shutdown();
199 }
200 if let Some(stop) = &self.reaper_stop {
203 stop.store(true, Ordering::Relaxed);
204 }
205 if let Some(j) = self
206 .reaper_join
207 .lock()
208 .unwrap_or_else(std::sync::PoisonError::into_inner)
209 .take()
210 {
211 let _ = j.join();
212 }
213 #[cfg(feature = "persist")]
214 for shard in self.shards_for_flush.iter() {
215 let mut g = lock_write(shard);
216 if let Some(aof) = &mut g.aof {
217 let _ = aof.sync_now();
224 }
225 }
226 #[cfg(all(feature = "replicate", not(target_arch = "wasm32")))]
229 if let Some((feed, dir)) = &self.feed_close {
230 Store::feed_write_close_marker(feed, dir);
231 }
232 }
233}