harmos_storage/manager/
lifecycle.rs1use super::*;
22
23impl<C> StorageManager<C> {
38 #[tracing::instrument(name = "storage.manager.lifecycle.start_with", level = "debug", skip_all, fields(outcome = "cancelled"))]
40 pub async fn start_with(&self, owner: Arc<()>, spawn: impl FnOnce(Worker) -> Result<Box<dyn WorkerOwner>>) -> Result<()> {
41 let result = async {
42 self.claim_owner(owner)?;
43 let mut lifecycle =
44 tracing::Instrument::instrument(self.inner.lifecycle.write(), tracing::trace_span!("storage.lock.wait")).await;
45 {
46 let state = self.inner.state.lock().unwrap();
47 if state.status.closing {
48 return Err(Error::Closing { domain: "storage" });
49 }
50 if state.ready && lifecycle.startup_complete {
51 return Ok(());
52 }
53 if state.ready {
54 return Err(Error::AlreadyRegistered {
55 domain: "storage",
56 name: WORKER_NAME.into(),
57 });
58 }
59 }
60 self.acquire_locked(&mut lifecycle).await?;
61 let mut state = self.inner.state.lock().unwrap();
62 if state.status.closing {
63 return Err(Error::Closing { domain: "storage" });
64 }
65 let worker = spawn(Worker(self.erased()))?;
66 state.ready = true;
67 state.status.running = true;
68 drop(state);
69 lifecycle.owner = Some(worker);
70 lifecycle.startup_complete = true;
71 self.inner.notify();
72 Ok(())
73 }
74 .await;
75 tracing::Span::current().record("outcome", if result.is_ok() { "completed" } else { "failed" });
76 result
77 }
78
79 pub fn settings(&self) -> &StorageSettings {
80 &self.inner.settings
81 }
82
83 #[tracing::instrument(name = "storage.manager.lifecycle.acquire", level = "debug", skip_all, fields(outcome = "cancelled"))]
84 pub async fn acquire(&self) -> Result<()> {
85 let result = async {
86 let mut lifecycle =
87 tracing::Instrument::instrument(self.inner.lifecycle.write(), tracing::trace_span!("storage.lock.wait")).await;
88 self.acquire_locked(&mut lifecycle).await
89 }
90 .await;
91 tracing::Span::current().record("outcome", if result.is_ok() { "completed" } else { "failed" });
92 result
93 }
94
95 #[tracing::instrument(name = "storage.manager.lifecycle.acquire_locked", level = "debug", skip_all)]
96 pub(super) async fn acquire_locked(&self, lifecycle: &mut Lifecycle) -> Result<()> {
97 if self.inner.state.lock().unwrap().status.closing {
98 return Err(Error::Closing { domain: "storage" });
99 }
100 if !lifecycle.primary_open {
101 lifecycle.primary_touched = true;
102 let saved = self.inner.bounded("primary.open", self.inner.primary.open()).await?;
103 self.inner.primary.history().check(&saved.history)?;
104 let mut state = self.inner.state.lock().unwrap();
105 state.status.accepted = saved.clone();
106 state.status.saved = saved;
107 state.data_attempted = state.status.accepted.sequence;
108 state.data_accepted.sequence = state.status.accepted.sequence;
109 lifecycle.primary_open = true;
110 }
111 if !lifecycle.files_recovered {
112 self.recover_files().await?;
113 lifecycle.files_recovered = true;
114 }
115 if !lifecycle.receipts_recovered {
116 self.recover_receipts().await?;
117 lifecycle.receipts_recovered = true;
118 }
119 if !lifecycle.recovery_open {
120 lifecycle.recovery_touched = true;
121 let saved = self.inner.bounded("recovery.open", self.inner.recovery.open()).await?;
122 self.inner.recovery.history().check(&saved.history)?;
123 let mut state = self.inner.state.lock().unwrap();
124 state.status.recovery_accepted = saved.clone();
125 state.status.recovery_saved = saved;
126 state.recovery_written.sequence = state.status.recovery_accepted.sequence;
127 state.recovery_accepted.sequence = state.status.recovery_accepted.sequence;
128 lifecycle.recovery_open = true;
129 }
130 if self.inner.state.lock().unwrap().status.closing {
131 return Err(Error::Closing { domain: "storage" });
132 }
133 Ok(())
134 }
135
136 pub fn same_instance<D>(&self, other: &StorageManager<D>) -> bool {
137 Arc::ptr_eq(&self.inner, &other.inner)
138 }
139
140 #[tracing::instrument(name = "storage.manager.lifecycle.claim_owner", level = "trace", skip_all)]
141 pub fn claim_owner(&self, owner: Arc<()>) -> Result<()> {
142 let mut state = self.inner.state.lock().unwrap();
143 if state.status.closing {
144 return Err(Error::Closing { domain: "storage" });
145 }
146 if let Some(current) = &state.service_owner {
147 if !Arc::ptr_eq(current, &owner) {
148 return Err(Error::AlreadyRegistered {
149 domain: "storage owner",
150 name: WORKER_NAME.to_owned(),
151 });
152 }
153 } else {
154 state.service_owner = Some(owner);
155 }
156 Ok(())
157 }
158
159 pub fn cursor_accepted(&self) -> StorageCursor {
160 self.inner.state.lock().unwrap().status.accepted.clone()
161 }
162
163 pub fn cursor_saved(&self) -> StorageCursor {
164 self.inner.state.lock().unwrap().status.saved.clone()
165 }
166
167 #[tracing::instrument(name = "storage.manager.lifecycle.status", level = "trace", skip_all)]
168 pub fn status(&self) -> StorageMetrics {
169 let mut state = self.inner.state.lock().unwrap();
170 state.collect();
171 state.status.clone()
172 }
173}
174
175