use crate::S3StorageClass;
use once_cell::sync::OnceCell;
use serde::Deserialize;
use std::path::PathBuf;
pub const UPLOAD_PART_SIZE: u64 = 8 * 1024 * 1024;
pub const UPLOAD_READ_SIZE: u64 = 1024 * 1024;
pub const CONCURRENT_UPLOAD_TASKS: u16 = 8;
pub const CONCURRENT_DOWNLOADER_TASKS: u16 = 8;
pub const CONCURRENT_SYNC_TASKS: u16 = 4;
pub const REQUEST_RETRIES: u16 = 5;
pub const CONCURRENT_WRITER_TASKS: u16 = 1;
#[derive(Debug, Deserialize)]
pub struct Config {
#[serde(default)]
storage_class: StorageClass,
#[serde(default)]
upload_part_size: UploadPartSize,
#[serde(default)]
upload_read_size: UploadReadSize,
#[serde(default)]
concurrent_upload_tasks: ConcurrentUploadTasks,
#[serde(default)]
concurrent_downloader_tasks: ConcurrentDownloaderTasks,
#[serde(default)]
concurrent_sync_tasks: ConcurrentSyncTasks,
#[serde(default)]
request_retries: RequestRetries,
#[serde(default)]
concurrent_writer_tasks: ConcurrentWriterTasks,
#[serde(default)]
temp_dir_path: TempDirPath,
}
#[derive(Debug, Deserialize, Default)]
#[serde(transparent)]
struct TempDirPath(Option<PathBuf>);
#[derive(Debug, Deserialize)]
#[serde(transparent)]
struct StorageClass(S3StorageClass);
impl Default for StorageClass {
fn default() -> Self {
StorageClass(S3StorageClass::Standard)
}
}
#[derive(Debug, Deserialize)]
#[serde(transparent)]
struct UploadPartSize(u64);
impl Default for UploadPartSize {
fn default() -> Self {
UploadPartSize(UPLOAD_PART_SIZE)
}
}
#[derive(Debug, Deserialize)]
#[serde(transparent)]
struct UploadReadSize(u64);
impl Default for UploadReadSize {
fn default() -> Self {
UploadReadSize(UPLOAD_READ_SIZE)
}
}
#[derive(Debug, Deserialize)]
#[serde(transparent)]
struct ConcurrentUploadTasks(u16);
impl Default for ConcurrentUploadTasks {
fn default() -> Self {
ConcurrentUploadTasks(CONCURRENT_UPLOAD_TASKS)
}
}
#[derive(Debug, Deserialize)]
#[serde(transparent)]
struct ConcurrentDownloaderTasks(u16);
impl Default for ConcurrentDownloaderTasks {
fn default() -> Self {
ConcurrentDownloaderTasks(CONCURRENT_DOWNLOADER_TASKS)
}
}
#[derive(Debug, Deserialize)]
#[serde(transparent)]
struct ConcurrentSyncTasks(u16);
impl Default for ConcurrentSyncTasks {
fn default() -> Self {
ConcurrentSyncTasks(CONCURRENT_SYNC_TASKS)
}
}
#[derive(Debug, Deserialize)]
#[serde(transparent)]
struct RequestRetries(u16);
impl Default for RequestRetries {
fn default() -> Self {
RequestRetries(REQUEST_RETRIES)
}
}
#[derive(Debug, Deserialize)]
#[serde(transparent)]
struct ConcurrentWriterTasks(u16);
impl Default for ConcurrentWriterTasks {
fn default() -> Self {
ConcurrentWriterTasks(CONCURRENT_WRITER_TASKS)
}
}
static CONFIG: OnceCell<Config> = OnceCell::new();
const EXPECT_GLOBAL_CONFIG: &str = "failed to parse config from environment";
impl Config {
pub fn global() -> &'static Config {
CONFIG.get_or_init(|| {
envy::prefixed("ESTHRI_")
.from_env::<Config>()
.expect(EXPECT_GLOBAL_CONFIG)
})
}
pub fn storage_class(&self) -> S3StorageClass {
self.storage_class.0
}
pub fn temp_dir_path(&self) -> Option<PathBuf> {
self.temp_dir_path.0.clone()
}
pub fn upload_part_size(&self) -> u64 {
self.upload_part_size.0
}
pub fn upload_read_size(&self) -> u64 {
self.upload_read_size.0
}
pub fn concurrent_upload_tasks(&self) -> usize {
self.concurrent_upload_tasks.0 as usize
}
pub fn concurrent_downloader_tasks(&self) -> usize {
self.concurrent_downloader_tasks.0 as usize
}
pub fn concurrent_sync_tasks(&self) -> usize {
self.concurrent_sync_tasks.0 as usize
}
pub fn request_retries(&self) -> usize {
self.request_retries.0 as usize
}
pub fn concurrent_writer_tasks(&self) -> usize {
self.concurrent_writer_tasks.0 as usize
}
}