-
Notifications
You must be signed in to change notification settings - Fork 746
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cleanup PVF artifact by cache limit and stale time #4662
Changes from 1 commit
988b73d
173f1cf
2b8ae5a
7f57911
19380a6
c8b2cee
9b1f82d
c519c51
a7e043b
61d3efb
7d0dea3
6144189
f27aced
23ca3b9
f8073b9
2dda9d9
09a0a97
edd0e0f
0c09ea8
f10c8eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -169,6 +169,15 @@ pub struct Artifacts { | |
inner: HashMap<ArtifactId, ArtifactState>, | ||
} | ||
|
||
/// A condition which we use to cleanup artifacts | ||
#[derive(Debug)] | ||
pub enum CleanupBy { | ||
// Inactive time after which artefact is deleted | ||
Time(Duration), | ||
// Max size in bytes. Reaching it older artefacts are deleted | ||
Size(u64), | ||
} | ||
|
||
impl Artifacts { | ||
#[cfg(test)] | ||
pub(crate) fn empty() -> Self { | ||
|
@@ -251,21 +260,47 @@ impl Artifacts { | |
}) | ||
} | ||
|
||
/// Remove artifacts older than the given TTL and return id and path of the removed ones. | ||
pub fn prune(&mut self, artifact_ttl: Duration) -> Vec<(ArtifactId, PathBuf)> { | ||
let now = SystemTime::now(); | ||
|
||
/// Remove artifacts older than the given TTL or the total artifacts size limit and return id | ||
/// and path of the removed ones. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doc comment needs fixing: we evict LRU artifacts only if we go over cache limit. |
||
pub fn prune(&mut self, cleanup_by: &CleanupBy) -> Vec<(ArtifactId, PathBuf)> { | ||
let mut to_remove = vec![]; | ||
for (k, v) in self.inner.iter() { | ||
if let ArtifactState::Prepared { last_time_needed, ref path, .. } = *v { | ||
if now | ||
.duration_since(last_time_needed) | ||
.map(|age| age > artifact_ttl) | ||
.unwrap_or(false) | ||
{ | ||
to_remove.push((k.clone(), path.clone())); | ||
|
||
match cleanup_by { | ||
CleanupBy::Time(artifact_ttl) => { | ||
let now = SystemTime::now(); | ||
for (k, v) in self.inner.iter() { | ||
if let ArtifactState::Prepared { last_time_needed, ref path, .. } = *v { | ||
if now | ||
.duration_since(last_time_needed) | ||
.map(|age| age > *artifact_ttl) | ||
.unwrap_or(false) | ||
{ | ||
to_remove.push((k.clone(), path.clone())); | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
CleanupBy::Size(size_limit) => { | ||
let mut total_size = 0; | ||
let mut artifact_sizes = vec![]; | ||
|
||
for (k, v) in self.inner.iter() { | ||
if let ArtifactState::Prepared { ref path, last_time_needed, .. } = *v { | ||
if let Ok(metadata) = fs::metadata(path) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What bothers me here is that we're running a (possibly large) number of synchronous blocking filesystem operations in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, added the size to artifact's state |
||
let size = metadata.len(); | ||
total_size += size; | ||
artifact_sizes.push((k.clone(), path.clone(), size, last_time_needed)); | ||
} | ||
} | ||
} | ||
artifact_sizes.sort_by_key(|&(_, _, _, last_time_needed)| last_time_needed); | ||
|
||
while total_size > *size_limit { | ||
let Some((artifact_id, path, size, _)) = artifact_sizes.pop() else { break }; | ||
to_remove.push((artifact_id, path)); | ||
total_size -= size; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A unit test to check the correctness of this behavior would be definitely appreciated :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added (and it saved me because the implementation was not correct) |
||
}, | ||
} | ||
|
||
for artifact in &to_remove { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment seems wrong, we delete least used ones. At least for me
older
usually means in relation to creation time.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed