WIP: starting adding tick() for cleanup storage #1
6 changed files with 53 additions and 23 deletions
|
@ -6,20 +6,20 @@ use serde::Deserialize;
|
||||||
#[derive(Deserialize, Clone)]
|
#[derive(Deserialize, Clone)]
|
||||||
pub struct MemoryStorageConfig {
|
pub struct MemoryStorageConfig {
|
||||||
pub max_size: usize,
|
pub max_size: usize,
|
||||||
pub ttl: usize,
|
pub ttl: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Clone)]
|
#[derive(Deserialize, Clone)]
|
||||||
pub struct DiskStorageConfig {
|
pub struct DiskStorageConfig {
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
pub ttl: usize,
|
pub ttl: u64,
|
||||||
pub max_size: usize,
|
pub max_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Clone)]
|
#[derive(Deserialize, Clone)]
|
||||||
pub struct MixedStorageConfig {
|
pub struct MixedStorageConfig {
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
pub ttl: usize,
|
pub ttl: u64,
|
||||||
pub max_size: usize,
|
pub max_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
19
src/main.rs
19
src/main.rs
|
@ -44,14 +44,17 @@ async fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
async fn launch_storages_tick(app_state: Arc<Mutex<AppState>>) {
|
async fn launch_storages_tick(app_state: Arc<Mutex<AppState>>) {
|
||||||
loop {
|
loop {
|
||||||
let mut app_state_locked = app_state.lock().await;
|
|
||||||
match app_state_locked.storage_pool.tick().await {
|
|
||||||
Ok(_) => todo!(),
|
|
||||||
Err(err) => println!("{}", err),
|
|
||||||
}
|
|
||||||
|
|
||||||
std::mem::drop(app_state_locked);
|
|
||||||
|
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||||
|
|
||||||
|
let mut app_state_locked = app_state.lock().await;
|
||||||
|
let results = app_state_locked.storage_pool.tick().await;
|
||||||
|
let errs = results
|
||||||
|
.into_iter()
|
||||||
|
.filter(anyhow::Result::is_err)
|
||||||
|
.map(anyhow::Result::unwrap_err);
|
||||||
|
|
||||||
|
for err in errs {
|
||||||
|
println!("error while tick {}", err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,21 @@ impl Storage for DiskStorage {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn tick(&self) -> anyhow::Result<()> {
|
async fn tick(&mut self) -> anyhow::Result<()> {
|
||||||
|
let paths_deleted = self
|
||||||
|
.items
|
||||||
|
.iter()
|
||||||
|
.filter(|(_, item)| item.created_at.elapsed().unwrap().as_secs() >= self.config.ttl)
|
||||||
|
.map(|(_, item)| item.path.clone())
|
||||||
|
.collect::<Vec<PathBuf>>();
|
||||||
|
|
||||||
|
self.items
|
||||||
|
.retain(|_, item| item.created_at.elapsed().unwrap().as_secs() < self.config.ttl);
|
||||||
|
|
||||||
|
for path in paths_deleted {
|
||||||
|
tokio::fs::remove_file(path).await?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
use std::{collections::HashMap, pin::Pin, time::SystemTime};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
pin::Pin,
|
||||||
|
time::{Duration, SystemTime},
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::Ok;
|
use anyhow::Ok;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
@ -43,7 +47,10 @@ impl Storage for MemoryStorage {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn tick(&self) -> anyhow::Result<()> {
|
async fn tick(&mut self) -> anyhow::Result<()> {
|
||||||
|
self.items
|
||||||
|
.retain(|_, item| item.created_at.elapsed().unwrap().as_secs() < self.config.ttl);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,10 +59,11 @@ impl Storage for MemoryStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn delete(&mut self, key: String) -> anyhow::Result<()> {
|
async fn delete(&mut self, key: String) -> anyhow::Result<()> {
|
||||||
self.items
|
if self.items.get(&key).is_some() {
|
||||||
.remove(&key)
|
self.items.remove(&key);
|
||||||
.ok_or_else(|| anyhow::anyhow!(""))
|
}
|
||||||
.map(|_| ())
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn retrieve(
|
async fn retrieve(
|
||||||
|
|
|
@ -36,7 +36,10 @@ impl Storage for MixedStorage {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn tick(&self) -> anyhow::Result<()> {
|
async fn tick(&mut self) -> anyhow::Result<()> {
|
||||||
|
self.disk.tick().await?;
|
||||||
|
self.memory.tick().await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ use self::{disk::DiskStorage, memory::MemoryStorage, mixed::MixedStorage};
|
||||||
pub trait Storage {
|
pub trait Storage {
|
||||||
async fn init(&mut self) -> anyhow::Result<()>;
|
async fn init(&mut self) -> anyhow::Result<()>;
|
||||||
async fn eligible(&self, src: String) -> bool;
|
async fn eligible(&self, src: String) -> bool;
|
||||||
async fn tick(&self) -> anyhow::Result<()>;
|
async fn tick(&mut self) -> anyhow::Result<()>;
|
||||||
async fn delete(&mut self, key: String) -> anyhow::Result<()>;
|
async fn delete(&mut self, key: String) -> anyhow::Result<()>;
|
||||||
async fn retrieve(
|
async fn retrieve(
|
||||||
&self,
|
&self,
|
||||||
|
@ -51,12 +51,14 @@ impl StoragePool {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn tick(&mut self) -> anyhow::Result<()> {
|
pub async fn tick(&mut self) -> Vec<anyhow::Result<()>> {
|
||||||
|
let mut results = vec![];
|
||||||
|
|
||||||
for item in &mut self.storages {
|
for item in &mut self.storages {
|
||||||
item.tick().await?;
|
results.push(item.tick().await);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
results
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn retrieve(
|
pub async fn retrieve(
|
||||||
|
|
Loading…
Reference in a new issue