Serialize startup prepared artifact reclamation
This commit is contained in:
parent
acd0b4cc8c
commit
7cd8a90af0
1 changed files with 195 additions and 67 deletions
|
|
@ -449,6 +449,60 @@ fn selected_gc_is_idempotent_only_at_the_durable_reclaim_boundary() {
|
|||
assert!(fixture.store.gc_artifacts(&[id]).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn concurrent_unleased_gc_serializes_observation_with_reclaim() {
|
||||
let fixture = Fixture::new();
|
||||
let artifact = fixture
|
||||
.store
|
||||
.prepare(&fixture.request(
|
||||
75,
|
||||
&[(
|
||||
layer(&[Entry {
|
||||
path: "payload",
|
||||
kind: EntryType::Regular,
|
||||
data: b"concurrent-gc",
|
||||
target: None,
|
||||
mode: 0o644,
|
||||
}]),
|
||||
OCI_TAR,
|
||||
)],
|
||||
))
|
||||
.unwrap();
|
||||
let (_, first) = fixture.independent_store();
|
||||
let (_, second) = fixture.independent_store();
|
||||
let barrier = Arc::new(Barrier::new(3));
|
||||
let first_barrier = Arc::clone(&barrier);
|
||||
let first = thread::spawn(move || {
|
||||
first_barrier.wait();
|
||||
first.gc_unleased_artifacts()
|
||||
});
|
||||
let second_barrier = Arc::clone(&barrier);
|
||||
let second = thread::spawn(move || {
|
||||
second_barrier.wait();
|
||||
second.gc_unleased_artifacts()
|
||||
});
|
||||
|
||||
barrier.wait();
|
||||
let results = [
|
||||
first.join().unwrap().unwrap(),
|
||||
second.join().unwrap().unwrap(),
|
||||
];
|
||||
assert_eq!(results.iter().map(Vec::len).sum::<usize>(), 1);
|
||||
assert_eq!(
|
||||
results.iter().flatten().next().unwrap().outcome,
|
||||
ReclaimOutcome::Removed
|
||||
);
|
||||
assert!(
|
||||
fixture
|
||||
.catalog
|
||||
.snapshot()
|
||||
.unwrap()
|
||||
.prepared_artifacts
|
||||
.is_empty()
|
||||
);
|
||||
assert!(!fixture.artifact_root(&artifact).exists());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn selected_artifact_excludes_gc_until_the_claim_is_released() {
|
||||
let fixture = Fixture::new();
|
||||
|
|
|
|||
Loading…
Reference in a new issue