use std::sync::Arc;
use std::time::Duration;
pub type SharedStorage = Arc<dyn FunctionStorage>;
mod fs;
mod memory;
#[cfg(feature = "sqlite")]
mod sqlite;
pub use fs::FsStorage;
pub use memory::MemoryStorage;
#[cfg(feature = "sqlite")]
pub use sqlite::SqliteStorage;
#[cfg(test)]
mod conformance;
pub trait FunctionStorage: Send + Sync {
fn kv_get(&self, scope: &[u8], key: &[u8]) -> Option<Vec<u8>>;
fn kv_put(&self, scope: &[u8], key: &[u8], value: &[u8]);
fn kv_del(&self, scope: &[u8], key: &[u8]);
fn append(&self, scope: &[u8], ns: &[u8], key: &[u8], value: Vec<u8>) -> i64;
fn scan(
&self,
scope: &[u8],
ns: &[u8],
key: &[u8],
after_id: i64,
limit: usize,
) -> Vec<(i64, Vec<u8>)>;
fn queue_push(&self, scope: &[u8], items: &[Vec<u8>]);
fn queue_pop(&self, scope: &[u8]) -> Option<Vec<u8>>;
fn clear(&self, scope: &[u8]);
fn gc(&self, ttl: Duration) {
let _ = ttl;
}
}
pub const DEFAULT_ORPHAN_TTL_SECS: u64 = 24 * 60 * 60;
pub fn orphan_ttl() -> Duration {
let secs = std::env::var("VGI_BUFFERING_STORE_TTL_SECS")
.ok()
.and_then(|v| v.parse::<u64>().ok())
.unwrap_or(DEFAULT_ORPHAN_TTL_SECS);
Duration::from_secs(secs)
}
pub fn default_storage() -> Arc<dyn FunctionStorage> {
let choice = std::env::var("VGI_WORKER_SHARED_STORAGE").unwrap_or_default();
let store: Arc<dyn FunctionStorage> = match choice.as_str() {
"memory" => Arc::new(MemoryStorage::new()),
"fs" => Arc::new(FsStorage::new()),
#[cfg(feature = "sqlite")]
"sqlite" => Arc::new(SqliteStorage::new()),
#[cfg(feature = "http-storage")]
"http" => Arc::new(http::HttpStorage::from_env()),
"" => {
#[cfg(feature = "sqlite")]
{
Arc::new(SqliteStorage::new())
}
#[cfg(not(feature = "sqlite"))]
{
Arc::new(FsStorage::new())
}
}
other => {
log::warn!("unknown VGI_WORKER_SHARED_STORAGE={other:?}; falling back to fs");
Arc::new(FsStorage::new())
}
};
store.gc(orphan_ttl());
store
}
#[cfg(feature = "http-storage")]
pub mod http;
#[cfg(feature = "http-storage")]
pub use http::HttpStorage;
pub(crate) fn process_uid() -> String {
#[cfg(unix)]
{
(unsafe { libc::getuid() }).to_string()
}
#[cfg(not(unix))]
{
"user".to_string()
}
}
pub(crate) fn harden_dir(path: &std::path::Path) {
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let _ = std::fs::set_permissions(path, std::fs::Permissions::from_mode(0o700));
}
#[cfg(not(unix))]
{
let _ = path;
}
}