Add simple ttl
This commit is contained in:
parent
2d530ec000
commit
662dc668db
21
src/main.rs
21
src/main.rs
@ -1,15 +1,19 @@
|
|||||||
use async_std::fs::{create_dir_all, File};
|
use async_std::fs::{create_dir_all, File};
|
||||||
use async_std::io::WriteExt;
|
use async_std::io::WriteExt;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::json;
|
||||||
use tide::{Request, Response, StatusCode};
|
use tide::{Request, Response, StatusCode};
|
||||||
use base64;
|
use base64;
|
||||||
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
const STORAGE_DIR: &str = "./storage";
|
const STORAGE_DIR: &str = "./storage";
|
||||||
|
const DEFAULT_TTL: u64 = 86400;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct StoreRequest {
|
struct StoreRequest {
|
||||||
key: String,
|
key: String,
|
||||||
value: String,
|
value: String,
|
||||||
|
ttl: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@ -24,18 +28,21 @@ struct RetrieveResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Store data on the filesystem
|
/// Store data on the filesystem
|
||||||
async fn store_data(key: &str, value: &[u8]) -> Result<(), String> {
|
async fn store_data(key: &str, value: &[u8], expires_at: SystemTime) -> Result<(), String> {
|
||||||
// Create directory based on the first 2 characters of the key
|
|
||||||
let dir_name = format!("{}/{}", STORAGE_DIR, &key[..2]);
|
let dir_name = format!("{}/{}", STORAGE_DIR, &key[..2]);
|
||||||
let file_path = format!("{}/{}", dir_name, &key[2..]);
|
let file_path = format!("{}/{}", dir_name, &key[2..]);
|
||||||
|
let metadata_path = format!("{}.meta", file_path);
|
||||||
|
|
||||||
// Create directory if it doesn't exist
|
|
||||||
create_dir_all(&dir_name).await.map_err(|e| e.to_string())?;
|
create_dir_all(&dir_name).await.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// Write value to file
|
|
||||||
let mut file = File::create(&file_path).await.map_err(|e| e.to_string())?;
|
let mut file = File::create(&file_path).await.map_err(|e| e.to_string())?;
|
||||||
file.write_all(value).await.map_err(|e| e.to_string())?;
|
file.write_all(value).await.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
let metadata = serde_json::to_string(&json!({ "expires_at": expires_at }))
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
|
let mut meta_file = File::create(&metadata_path).await.map_err(|e| e.to_string())?;
|
||||||
|
meta_file.write_all(metadata.as_bytes()).await.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,8 +74,12 @@ async fn handle_store(mut req: Request<()>) -> tide::Result<Response> {
|
|||||||
tide::Error::from_str(StatusCode::BadRequest, "Invalid Base64 value")
|
tide::Error::from_str(StatusCode::BadRequest, "Invalid Base64 value")
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let now = SystemTime::now();
|
||||||
|
let live_for = if let Some(ttl) = data.ttl { Duration::from_secs(ttl) } else { Duration::from_secs(DEFAULT_TTL) };
|
||||||
|
let expires_at = now.checked_add(live_for).ok_or(tide::Error::from_str(StatusCode::BadRequest, "Invalid ttl"))?;
|
||||||
|
|
||||||
// Store the data
|
// Store the data
|
||||||
store_data(&data.key, &value_bytes).await.map_err(|e| {
|
store_data(&data.key, &value_bytes, expires_at).await.map_err(|e| {
|
||||||
tide::Error::from_str(StatusCode::InternalServerError, e)
|
tide::Error::from_str(StatusCode::InternalServerError, e)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user