Skip to content

Commit 7ceed49

Browse files
committed
feat: add back gc protect callback
1 parent 0fdcd63 commit 7ceed49

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

src/store/fs/gc.rs

Lines changed: 32 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 {
@@ -179,7 +196,17 @@ pub async fn gc_run_once(store: &Store, live: &mut HashSet<Hash>) -> crate::api:
179196
pub async fn run_gc(store: Store, config: GcConfig) {
180197
let mut live = HashSet::new();
181198
loop {
199+
live.clear();
182200
tokio::time::sleep(config.interval).await;
201+
if let Some(ref cb) = config.add_protected {
202+
match (cb)(&mut live).await {
203+
ProtectOutcome::Continue => {}
204+
ProtectOutcome::Skip => {
205+
info!("Skip gc run: protect callback indicated skip");
206+
continue;
207+
}
208+
}
209+
}
183210
if let Err(e) = gc_run_once(&store, &mut live).await {
184211
error!("error during gc run: {e}");
185212
break;
@@ -284,6 +311,7 @@ mod tests {
284311
assert!(!data_path.exists());
285312
assert!(!outboard_path.exists());
286313
}
314+
live.clear();
287315
// create a large partial file and check that the data and outboard file as well as
288316
// the sizes and bitfield files are deleted by gc
289317
{

src/store/fs/options.rs

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

7-
use super::{gc::GcConfig, meta::raw_outboard_size, temp_name};
7+
pub use super::gc::{GcConfig, ProtectCb, ProtectOutcome};
8+
use super::{meta::raw_outboard_size, temp_name};
89
use crate::Hash;
910

1011
/// Options for directories used by the file store.

0 commit comments

Comments
 (0)