Add calculate_sizes implementation as dispatchable job
Signed-off-by: trivernis <trivernis@protonmail.com>feature/jobs
parent
a57a6f32c4
commit
2f11c87395
@ -0,0 +1,90 @@
|
||||
use crate::jobs::Job;
|
||||
use crate::status_utils::SimpleProgress;
|
||||
use async_trait::async_trait;
|
||||
use mediarepo_core::error::{RepoError, RepoResult};
|
||||
use mediarepo_core::mediarepo_api::types::repo::SizeType;
|
||||
use mediarepo_core::settings::Settings;
|
||||
use mediarepo_core::utils::get_folder_size;
|
||||
use mediarepo_logic::dao::repo::Repo;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use tokio::fs;
|
||||
use tokio::sync::broadcast::{self, Sender};
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
pub struct CalculateSizesState {
|
||||
pub progress: SimpleProgress,
|
||||
pub sizes_channel: Sender<(SizeType, u64)>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CalculateSizesJob {
|
||||
repo_path: PathBuf,
|
||||
settings: Settings,
|
||||
state: Arc<RwLock<CalculateSizesState>>,
|
||||
}
|
||||
|
||||
impl CalculateSizesJob {
|
||||
pub fn new(repo_path: PathBuf, settings: Settings) -> Self {
|
||||
let (tx, _) = broadcast::channel(4);
|
||||
Self {
|
||||
repo_path,
|
||||
settings,
|
||||
state: Arc::new(RwLock::new(CalculateSizesState {
|
||||
sizes_channel: tx,
|
||||
progress: SimpleProgress::new(4),
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Job for CalculateSizesJob {
|
||||
type JobState = CalculateSizesState;
|
||||
|
||||
fn state(&self) -> Arc<RwLock<Self::JobState>> {
|
||||
self.state.clone()
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all)]
|
||||
async fn run(&self, repo: Arc<Repo>) -> RepoResult<()> {
|
||||
let size_types = vec![
|
||||
SizeType::Total,
|
||||
SizeType::FileFolder,
|
||||
SizeType::ThumbFolder,
|
||||
SizeType::DatabaseFile,
|
||||
];
|
||||
for size_type in size_types {
|
||||
let size = calculate_size(&size_type, &repo, &self.repo_path, &self.settings).await?;
|
||||
let mut state = self.state.write().await;
|
||||
state
|
||||
.sizes_channel
|
||||
.send((size_type, size))
|
||||
.map_err(|_| RepoError::from("failed to broadcast new size"))?;
|
||||
state.progress.tick();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
async fn calculate_size(
|
||||
size_type: &SizeType,
|
||||
repo: &Repo,
|
||||
repo_path: &PathBuf,
|
||||
settings: &Settings,
|
||||
) -> RepoResult<u64> {
|
||||
let size = match &size_type {
|
||||
SizeType::Total => get_folder_size(repo_path.clone()).await?,
|
||||
SizeType::FileFolder => repo.get_main_store_size().await?,
|
||||
SizeType::ThumbFolder => repo.get_thumb_store_size().await?,
|
||||
SizeType::DatabaseFile => {
|
||||
let db_path = settings.paths.db_file_path(repo_path);
|
||||
|
||||
let database_metadata = fs::metadata(db_path).await?;
|
||||
database_metadata.len()
|
||||
}
|
||||
};
|
||||
|
||||
Ok(size)
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
pub struct SimpleProgress {
|
||||
pub current: u64,
|
||||
pub total: u64,
|
||||
}
|
||||
|
||||
impl Default for SimpleProgress {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
total: 100,
|
||||
current: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SimpleProgress {
|
||||
pub fn new(total: u64) -> Self {
|
||||
Self { total, current: 0 }
|
||||
}
|
||||
|
||||
/// Increments the current progress by 1
|
||||
pub fn tick(&mut self) {
|
||||
self.current += 1;
|
||||
}
|
||||
|
||||
/// Sets the current progress to a defined value
|
||||
pub fn set_current(&mut self, current: u64) {
|
||||
self.current = current;
|
||||
}
|
||||
|
||||
/// Returns the total progress in percent
|
||||
pub fn percent(&self) -> f64 {
|
||||
(self.current as f64) / (self.total as f64)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue