Skip to main content

aven_core/attachments/
lifecycle.rs

1#![allow(dead_code)]
2
3use std::path::{Path, PathBuf};
4use std::time::Duration;
5
6use chrono::{DateTime, SecondsFormat, Utc};
7
8mod filesystem;
9mod leases;
10mod liveness;
11mod maintenance;
12mod quota;
13mod report;
14#[cfg(test)]
15mod test_support;
16
17pub const DEFAULT_LOCAL_GRACE: Duration = Duration::from_secs(7 * 24 * 60 * 60);
18pub const DEFAULT_ORIGINAL_QUOTA_BYTES: i64 = 10 * 1024 * 1024 * 1024;
19pub const DEFAULT_PREVIEW_QUOTA_BYTES: u64 = 512 * 1024 * 1024;
20pub const DEFAULT_MAINTENANCE_LIMIT: usize = 128;
21const LEASE_TTL: Duration = Duration::from_secs(10 * 60);
22
23pub trait Clock: Send + Sync {
24    fn now(&self) -> DateTime<Utc>;
25}
26
27pub struct SystemClock;
28
29impl Clock for SystemClock {
30    fn now(&self) -> DateTime<Utc> {
31        Utc::now()
32    }
33}
34
35#[derive(Debug, Clone, Copy)]
36pub struct LifecyclePolicy {
37    pub grace: Duration,
38    pub quota_bytes: i64,
39    pub preview_quota_bytes: u64,
40    pub maintenance_limit: usize,
41}
42
43impl Default for LifecyclePolicy {
44    fn default() -> Self {
45        Self {
46            grace: DEFAULT_LOCAL_GRACE,
47            quota_bytes: DEFAULT_ORIGINAL_QUOTA_BYTES,
48            preview_quota_bytes: DEFAULT_PREVIEW_QUOTA_BYTES,
49            maintenance_limit: DEFAULT_MAINTENANCE_LIMIT,
50        }
51    }
52}
53
54#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
55pub struct ByteCount {
56    pub count: u64,
57    pub bytes: u64,
58}
59
60#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
61pub struct LifecycleReport {
62    pub referenced: ByteCount,
63    pub protected: ByteCount,
64    pub grace_period: ByteCount,
65    pub eligible: ByteCount,
66    pub staging: ByteCount,
67    pub trash: ByteCount,
68    pub reservations: ByteCount,
69    pub quota: ByteCount,
70    pub inconsistencies: ByteCount,
71}
72
73#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
74pub struct PruneSummary {
75    pub eligible: ByteCount,
76    pub pruned: ByteCount,
77}
78
79fn timestamp(now: DateTime<Utc>) -> String {
80    now.to_rfc3339_opts(SecondsFormat::Secs, true)
81}
82
83fn cutoff(now: DateTime<Utc>, grace: Duration) -> anyhow::Result<String> {
84    let grace = chrono::Duration::from_std(grace)?;
85    Ok(timestamp(now - grace))
86}
87
88fn trash_dir(blob_dir: &Path) -> PathBuf {
89    blob_dir.join("trash")
90}
91
92fn staging_dir(blob_dir: &Path) -> PathBuf {
93    blob_dir.join("objects").join("sha256")
94}
95
96pub use leases::{acquire_lease, release_lease};
97pub use liveness::reconcile_liveness;
98pub(crate) use liveness::{
99    reconcile_liveness_for_hashes_in_transaction, reconcile_liveness_in_transaction,
100};
101#[cfg(test)]
102pub(crate) use maintenance::reconcile_missing_objects;
103pub use maintenance::{prune, prune_preview_cache};
104pub use quota::{ensure_local_capacity, release_reservation, reserve_upload};
105pub use report::lifecycle_report;