mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-13 02:25:51 -04:00
feat(base): Add setting for frequency of automatic media cache cleanups
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
This commit is contained in:
@@ -79,6 +79,17 @@ pub struct MediaRetentionPolicy {
|
||||
/// Defaults to 60 days.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub last_access_expiry: Option<Duration>,
|
||||
|
||||
/// The duration between two automatic media cache cleanups.
|
||||
///
|
||||
/// If this is set, a cleanup will be triggered after the given duration
|
||||
/// is elapsed, at the next call to the media cache API. If this is set to
|
||||
/// zero, each call to the media cache API will trigger a cleanup. If this
|
||||
/// is `None`, cleanups will only occur if they are triggered manually.
|
||||
///
|
||||
/// Defaults to running cleanups daily.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub cleanup_frequency: Option<Duration>,
|
||||
}
|
||||
|
||||
impl MediaRetentionPolicy {
|
||||
@@ -91,7 +102,12 @@ impl MediaRetentionPolicy {
|
||||
///
|
||||
/// This means that all media will be cached and cleanups have no effect.
|
||||
pub fn empty() -> Self {
|
||||
Self { max_cache_size: None, max_file_size: None, last_access_expiry: None }
|
||||
Self {
|
||||
max_cache_size: None,
|
||||
max_file_size: None,
|
||||
last_access_expiry: None,
|
||||
cleanup_frequency: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the maximum authorized size of the overall media cache, in bytes.
|
||||
@@ -113,6 +129,12 @@ impl MediaRetentionPolicy {
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the duration between two automatic media cache cleanups.
|
||||
pub fn with_cleanup_frequency(mut self, duration: Option<Duration>) -> Self {
|
||||
self.cleanup_frequency = duration;
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether this policy has limitations.
|
||||
///
|
||||
/// If this policy has no limitations, a cleanup job would have no effect.
|
||||
@@ -178,6 +200,24 @@ impl MediaRetentionPolicy {
|
||||
.is_ok_and(|elapsed| elapsed >= max_duration)
|
||||
})
|
||||
}
|
||||
|
||||
/// Whether an automatic media cache cleanup should be triggered given the
|
||||
/// time of the last cleanup.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `current_time` - The current time.
|
||||
///
|
||||
/// * `last_cleanup_time` - The time of the last media cache cleanup.
|
||||
pub fn should_clean_up(&self, current_time: SystemTime, last_cleanup_time: SystemTime) -> bool {
|
||||
self.cleanup_frequency.is_some_and(|max_duration| {
|
||||
current_time
|
||||
.duration_since(last_cleanup_time)
|
||||
// If this returns an error, the last cleanup time is newer than the current time.
|
||||
// This shouldn't happen but in this case no cleanup job is needed.
|
||||
.is_ok_and(|elapsed| elapsed >= max_duration)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for MediaRetentionPolicy {
|
||||
@@ -189,6 +229,8 @@ impl Default for MediaRetentionPolicy {
|
||||
max_file_size: Some(20 * 1024 * 1024),
|
||||
// 60 days.
|
||||
last_access_expiry: Some(Duration::from_secs(60 * 24 * 60 * 60)),
|
||||
// 1 day.
|
||||
cleanup_frequency: Some(Duration::from_secs(24 * 60 * 60)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -327,4 +369,36 @@ mod tests {
|
||||
assert!(policy.has_content_expired(epoch_plus_60, last_access_time));
|
||||
assert!(policy.has_content_expired(epoch_plus_120, last_access_time));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_media_retention_policy_cleanup_frequency() {
|
||||
let epoch = SystemTime::UNIX_EPOCH;
|
||||
let epoch_plus_60 = epoch + Duration::from_secs(60);
|
||||
let epoch_plus_120 = epoch + Duration::from_secs(120);
|
||||
|
||||
let mut policy = MediaRetentionPolicy::empty();
|
||||
assert!(!policy.should_clean_up(epoch_plus_60, epoch));
|
||||
assert!(!policy.should_clean_up(epoch_plus_60, epoch_plus_60));
|
||||
assert!(!policy.should_clean_up(epoch_plus_60, epoch_plus_120));
|
||||
|
||||
policy = policy.with_cleanup_frequency(Some(Duration::from_secs(0)));
|
||||
assert!(policy.should_clean_up(epoch_plus_60, epoch));
|
||||
assert!(policy.should_clean_up(epoch_plus_60, epoch_plus_60));
|
||||
assert!(!policy.should_clean_up(epoch_plus_60, epoch_plus_120));
|
||||
|
||||
policy = policy.with_cleanup_frequency(Some(Duration::from_secs(30)));
|
||||
assert!(policy.should_clean_up(epoch_plus_60, epoch));
|
||||
assert!(!policy.should_clean_up(epoch_plus_60, epoch_plus_60));
|
||||
assert!(!policy.should_clean_up(epoch_plus_60, epoch_plus_120));
|
||||
|
||||
policy = policy.with_cleanup_frequency(Some(Duration::from_secs(60)));
|
||||
assert!(policy.should_clean_up(epoch_plus_60, epoch));
|
||||
assert!(!policy.should_clean_up(epoch_plus_60, epoch_plus_60));
|
||||
assert!(!policy.should_clean_up(epoch_plus_60, epoch_plus_120));
|
||||
|
||||
policy = policy.with_cleanup_frequency(Some(Duration::from_secs(90)));
|
||||
assert!(!policy.should_clean_up(epoch_plus_60, epoch));
|
||||
assert!(!policy.should_clean_up(epoch_plus_60, epoch_plus_60));
|
||||
assert!(!policy.should_clean_up(epoch_plus_60, epoch_plus_120));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user