Skip to content

Commit 8f397c4

Browse files
committed
feat: add back gc protect callback
1 parent 0fdcd63 commit 8f397c4

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

src/store/fs/gc.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use std::collections::HashSet;
1+
use std::{collections::HashSet, pin::Pin, sync::Arc};
22

33
use bao_tree::ChunkRanges;
44
use genawaiter::sync::{Co, Gen};
55
use n0_future::{Stream, StreamExt};
6-
use tracing::{debug, error, warn};
6+
use tracing::{debug, error, info, warn};
77

88
use crate::{api::Store, Hash, HashAndFormat};
99

@@ -130,14 +130,31 @@ fn gc_sweep<'a>(
130130
})
131131
}
132132

133-
#[derive(Debug, Clone)]
133+
#[derive(derive_more::Debug, Clone)]
134134
pub struct GcConfig {
135135
pub interval: std::time::Duration,
136+
#[debug("ProtectCallback")]
137+
pub add_protected: Option<ProtectCb>,
136138
}
137139

140+
#[derive(Debug)]
141+
pub enum ProtectOutcome {
142+
Continue,
143+
Skip,
144+
}
145+
146+
pub type ProtectCb = Arc<
147+
dyn for<'a> Fn(
148+
&'a mut HashSet<Hash>,
149+
)
150+
-> Pin<Box<dyn std::future::Future<Output = ProtectOutcome> + Send + Sync + 'a>>
151+
+ Send
152+
+ Sync
153+
+ 'static,
154+
>;
155+
138156
pub async fn gc_run_once(store: &Store, live: &mut HashSet<Hash>) -> crate::api::Result<()> {
139157
{
140-
live.clear();
141158
store.clear_protected().await?;
142159
let mut stream = gc_mark(store, live);
143160
while let Some(ev) = stream.next().await {
@@ -180,6 +197,15 @@ pub async fn run_gc(store: Store, config: GcConfig) {
180197
let mut live = HashSet::new();
181198
loop {
182199
tokio::time::sleep(config.interval).await;
200+
if let Some(ref cb) = config.add_protected {
201+
match (cb)(&mut live).await {
202+
ProtectOutcome::Continue => {}
203+
ProtectOutcome::Skip => {
204+
info!("Skip gc run: protect callback indicated skip");
205+
continue;
206+
}
207+
}
208+
}
183209
if let Err(e) = gc_run_once(&store, &mut live).await {
184210
error!("error during gc run: {e}");
185211
break;
@@ -284,6 +310,7 @@ mod tests {
284310
assert!(!data_path.exists());
285311
assert!(!outboard_path.exists());
286312
}
313+
live.clear();
287314
// create a large partial file and check that the data and outboard file as well as
288315
// the sizes and bitfield files are deleted by gc
289316
{

src/store/fs/options.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ use std::{
44
time::Duration,
55
};
66

7-
use super::{gc::GcConfig, meta::raw_outboard_size, temp_name};
7+
use super::{meta::raw_outboard_size, temp_name};
88
use crate::Hash;
99

10+
pub use super::gc::{GcConfig, ProtectCb, ProtectOutcome};
11+
1012
/// Options for directories used by the file store.
1113
#[derive(Debug, Clone)]
1214
pub struct PathOptions {

0 commit comments

Comments
 (0)