aven_core/attachments/
lifecycle.rs1#![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;
21pub(crate) const 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::reconcile_liveness_for_hashes_in_transaction;
99#[cfg(test)]
100pub(crate) use maintenance::reconcile_missing_objects;
101pub use maintenance::{prune, prune_preview_cache};
102pub use quota::{ensure_local_capacity, release_reservation};
103pub use report::lifecycle_report;