Skip to content
This repository has been archived by the owner on Jan 11, 2024. It is now read-only.

Commit

Permalink
FM-359: Remove old snapshots (#425)
Browse files Browse the repository at this point in the history
  • Loading branch information
aakoshh authored Nov 27, 2023
1 parent 1d56a2e commit 0de9778
Showing 1 changed file with 39 additions and 1 deletion.
40 changes: 39 additions & 1 deletion fendermint/vm/snapshot/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ pub struct SnapshotManager<BS> {
snapshot_dir: PathBuf,
/// Target size in bytes for snapshot chunks.
snapshot_chunk_size: usize,
/// Number of snapshots to keep.
///
/// 0 means unlimited.
snapshot_history_size: usize,
/// Shared state of snapshots.
snapshot_state: SnapshotState,
/// How often to check CometBFT whether it has finished syncing.
Expand All @@ -78,6 +82,7 @@ where
snapshot_interval: BlockHeight,
snapshot_dir: PathBuf,
snapshot_chunk_size: usize,
snapshot_history_size: usize,
sync_poll_interval: Duration,
) -> anyhow::Result<(Self, SnapshotClient)> {
let snapshot_items = list_manifests(&snapshot_dir).context("failed to list manifests")?;
Expand All @@ -93,6 +98,7 @@ where
store,
snapshot_dir,
snapshot_chunk_size,
snapshot_history_size,
snapshot_state: snapshot_state.clone(),
sync_poll_interval,
// Assume we are syncing until we can determine otherwise.
Expand Down Expand Up @@ -170,10 +176,41 @@ where
}
}

// Delete old snapshots.
self.prune_history().await;

last_params = Some((state_params, block_height));
}
}

/// Remove snapshot directories if we have more than the desired history size.
async fn prune_history(&self) {
if self.snapshot_history_size == 0 {
return;
}

let removables = atomically(|| {
self.snapshot_state.snapshots.modify_mut(|snapshots| {
let mut removables = Vec::new();
while snapshots.len() > self.snapshot_history_size {
if let Some(snapshot) = snapshots.pop_front() {
removables.push(snapshot);
} else {
break;
}
}
removables
})
})
.await;

for r in removables {
if let Err(e) = std::fs::remove_dir_all(&r.snapshot_dir) {
tracing::error!(error =? e, snapshot_dir = r.snapshot_dir.to_string_lossy().to_string(), "failed to remove snapsot");
}
}
}

/// Export a snapshot to a temporary file, then copy it to the snapshot directory.
async fn create_snapshot(
&self,
Expand Down Expand Up @@ -362,6 +399,7 @@ mod tests {
1,
temp_dir.path().into(),
10000,
1,
never_poll_sync,
)
.expect("failed to create snapshot manager");
Expand Down Expand Up @@ -412,7 +450,7 @@ mod tests {

// Create a new manager instance
let (_, new_client) =
SnapshotManager::new(store, 1, temp_dir.path().into(), 10000, never_poll_sync)
SnapshotManager::new(store, 1, temp_dir.path().into(), 10000, 1, never_poll_sync)
.expect("failed to create snapshot manager");

let snapshots = atomically(|| new_client.list_snapshots()).await;
Expand Down

0 comments on commit 0de9778

Please sign in to comment.