Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions objectstore-server/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ use objectstore_service::backend::local_fs::FileSystemConfig;
#[cfg(feature = "storage-cogs")]
use objectstore_service::change_stream::CostTrackerConfig;
use objectstore_service::encryption::Cipher;
use objectstore_service::garbage_collector::GarbageCollectorConfig;
use objectstore_types::auth::Permission;
use secrecy::{CloneableSecret, SecretBox, SerializableSecret, zeroize::Zeroize};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -550,6 +551,32 @@ pub struct Config {
#[serde(default)]
pub storage_cogs: Option<CostTrackerConfig>,

/// Garbage collector configuration.
///
/// Selects the backend of the garbage collector's expiration index, which records, per
/// object, the deadline at which that object becomes eligible for deletion. The index is
/// kept in sync on the write path and read back by the collector to find expired objects,
/// so it must be configured with the same lifetime as the storage backend: an index that
/// is lost or reset leaves objects behind with nothing scheduling their deletion.
///
/// `None` is the default: no expiration index is configured.
///
/// # Environment Variables
///
/// - `OS__GARBAGE_COLLECTOR__TYPE=sqlite`
/// - `OS__GARBAGE_COLLECTOR__PATH=/data/objectstore.db`
///
/// # Example
///
/// ```yaml
/// garbage_collector:
/// type: sqlite
/// path: /data/objectstore.db
/// ```
///
/// See [`GarbageCollectorConfig`] for the available backends and their fields.
pub garbage_collector: Option<GarbageCollectorConfig>,

/// Configuration of the internal task runtime.
///
/// Controls the thread pool size and behavior of the async runtime powering the server.
Expand Down Expand Up @@ -858,6 +885,7 @@ impl Default for Config {

#[cfg(feature = "storage-cogs")]
storage_cogs: None,
garbage_collector: None,
runtime: Runtime::default(),
logging: LoggingConfig::default(),
sentry: Sentry::default(),
Expand Down
26 changes: 26 additions & 0 deletions objectstore-service/src/garbage_collector/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ pub mod sqlite;
use std::fmt::Debug;

use objectstore_types::time::Timestamp;
use serde::{Deserialize, Serialize};

use crate::change_stream::ChangeStreamError;
use crate::garbage_collector::sqlite::SqliteGarbageCollectorConfig;
use crate::id::ObjectId;

/// Stores object expiration metadata for the garbage collector.
Expand Down Expand Up @@ -49,3 +51,27 @@ pub trait GcStorage: Send + Sync + Debug {
limit: u64,
) -> Result<Vec<ObjectId>, ChangeStreamError>;
}

/// Backend selection for the garbage collector's expiration index.
///
/// Each variant wraps that backend's own configuration and corresponds to a [`GcStorage`]
/// implementation. The enum is internally tagged: in YAML the variant is named by a `type`
/// key, and through environment variables by the `OS__GARBAGE_COLLECTOR__TYPE` prefix plus
/// the variant's fields (e.g. `OS__GARBAGE_COLLECTOR__TYPE=sqlite`).
///
/// ```yaml
/// garbage_collector:
/// type: sqlite
/// path: /data/objectstore.db
/// ```
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum GarbageCollectorConfig {
/// SQLite-backed index, serialized as `type: sqlite`.
///
/// Stores one row per object in a local SQLite database, see
/// [`SqliteGarbageCollectorConfig`] for its fields. The database file must live on
/// storage that survives restarts and is shared by every server that writes objects,
/// otherwise the index diverges from the objects actually stored.
Sqlite(SqliteGarbageCollectorConfig),
}
Loading