use super::*;
impl<C> StorageManager<C> {
pub async fn close(&self) -> Result<()> {
{
let mut state = self.inner.state.lock().unwrap();
state.status.closing = true;
state.close_followers();
}
self.inner.notify();
let mut lifecycle = self.inner.lifecycle.write().await;
let ready = {
let state = self.inner.state.lock().unwrap();
state.ready && !state.status.closed
};
if ready {
self.settle_transition().await;
self.settle_files().await?;
self.settle_deletions().await?;
let files = self.capture_files(None)?;
self.flush_domain(Domain::Data, None).await?;
self.persist_files(&files).await?;
self.retire_files();
self.flush_recovery().await?;
}
if ready {
self.release_snapshots().await?;
}
let mut changed = self.inner.changed.subscribe();
loop {
{
let state = self.inner.state.lock().unwrap();
if !state.pruning_objects {
break;
}
if !state.status.running {
return Err(Error::NotReady { domain: "storage worker" });
}
}
changed.changed().await.map_err(|_| Error::NotReady { domain: "storage" })?;
}
if lifecycle.primary_touched && !lifecycle.primary_closed {
self.inner.primary.close().await?;
lifecycle.primary_closed = true;
}
if lifecycle.recovery_touched && !lifecycle.recovery_closed {
self.inner.recovery.close().await?;
lifecycle.recovery_closed = true;
}
self.retire_files();
{
let mut state = self.inner.state.lock().unwrap();
state.receipts.clear();
state.status.closed = true;
state.collect();
}
self.inner.notify();
if let Some(owner) = &lifecycle.owner {
owner.stop().await?;
}
lifecycle.owner = None;
self.inner.state.lock().unwrap().status.running = false;
self.inner.notify();
Ok(())
}
pub(super) fn check_raw_recovery(&self) -> Result<()> {
if self.inner.state.lock().unwrap().journal_saved.is_some() {
return Err(Error::InvalidInput { field: "recovery ownership", reason: "managed journal owns recovery writes" });
}
Ok(())
}
}