cache trait accepts a bytestream instead

feature/v32-tokens
Edward Shen 2021-04-14 23:44:13 -04:00
parent 8949e41bee
commit c25b8be45b
Signed by: edward
GPG Key ID: 19182661E818369F
5 changed files with 40 additions and 26 deletions

16
src/cache/low_mem.rs vendored
View File

@ -7,17 +7,17 @@ use bytes::Bytes;
use futures::Stream;
use lru::LruCache;
use super::{fs::FromFsStream, Cache, CacheKey};
use super::{fs::FromFsStream, ByteStream, Cache, CacheKey};
pub struct LowMemCache {
on_disk: LruCache<CacheKey, ()>,
disk_path: PathBuf,
disk_max_size: usize,
disk_cur_size: usize,
disk_max_size: u64,
disk_cur_size: u64,
}
impl LowMemCache {
pub fn new(disk_max_size: usize, disk_path: PathBuf) -> Self {
pub fn new(disk_max_size: u64, disk_path: PathBuf) -> Self {
Self {
on_disk: LruCache::unbounded(),
disk_path,
@ -37,10 +37,8 @@ impl Cache for LowMemCache {
}
}
async fn put_stream(
&mut self,
key: CacheKey,
image: impl Stream<Item = Result<Bytes, reqwest::Error>> + Unpin + Send + 'static,
) {
async fn put_stream(&mut self, key: CacheKey, image: ByteStream) {
// this call has a side effect and the returned future is for reading
let _ = super::fs::transparent_file_stream(&PathBuf::from(key), image);
}
}

21
src/cache/mod.rs vendored
View File

@ -131,7 +131,7 @@ impl ImageMetadata {
}
#[async_trait]
pub trait Cache {
pub trait Cache: Send + Sync {
async fn get(&mut self, _key: &CacheKey) -> Option<&(CachedImage, ImageMetadata)> {
unimplemented!()
}
@ -147,11 +147,20 @@ pub trait Cache {
unimplemented!()
}
async fn put_stream(
&mut self,
_key: CacheKey,
_image: impl Stream<Item = Result<Bytes, reqwest::Error>> + Unpin + Send + 'static,
) {
async fn put_stream(&mut self, _key: CacheKey, _image: ByteStream) {
unimplemented!()
}
}
pub enum ByteStream {}
impl Stream for ByteStream {
type Item = Result<Bytes, reqwest::Error>;
fn poll_next(
self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Option<Self::Item>> {
todo!()
}
}

View File

@ -34,6 +34,6 @@ pub struct CliArgs {
/// reasons.
#[clap(long, env = "ENABLE_SERVER_STRING", takes_value = false)]
pub enable_server_string: bool,
#[clap(short, long, conflicts_with("memory_quota"))]
#[clap(short, long, conflicts_with("memory_quota"), env = "LOW_MEMORY_MODE")]
pub low_memory: bool,
}

View File

@ -12,7 +12,7 @@ use std::{num::ParseIntError, sync::atomic::Ordering};
use actix_web::rt::{spawn, time, System};
use actix_web::web::{self, Data};
use actix_web::{App, HttpServer};
use cache::GenerationalCache;
use cache::{Cache, GenerationalCache, LowMemCache};
use clap::Clap;
use config::CliArgs;
use log::{debug, error, warn, LevelFilter};
@ -54,6 +54,7 @@ async fn main() -> Result<(), std::io::Error> {
let memory_max_size = cli_args.memory_quota.get();
let disk_quota = cli_args.disk_quota;
let cache_path = cli_args.cache_path.clone();
let low_mem_mode = cli_args.low_memory;
SimpleLogger::new()
.with_level(LevelFilter::Info)
@ -106,16 +107,22 @@ async fn main() -> Result<(), std::io::Error> {
// Start HTTPS server
HttpServer::new(move || {
let cache: Box<dyn Cache> = if low_mem_mode {
Box::new(LowMemCache::new(disk_quota, cache_path.clone()))
} else {
Box::new(GenerationalCache::new(
memory_max_size,
disk_quota,
cache_path.clone(),
))
};
App::new()
.service(routes::token_data)
.service(routes::token_data_saver)
.route("{tail:.*}", web::get().to(routes::default))
.app_data(Data::from(Arc::clone(&data_1)))
.app_data(Data::new(Mutex::new(GenerationalCache::new(
memory_max_size,
disk_quota,
cache_path.clone(),
))))
.app_data(Data::new(Mutex::new(cache)))
})
.shutdown_timeout(60)
.bind_rustls(format!("0.0.0.0:{}", port), tls_config)?

View File

@ -18,7 +18,7 @@ use serde::Deserialize;
use sodiumoxide::crypto::box_::{open_precomputed, Nonce, PrecomputedKey, NONCEBYTES};
use thiserror::Error;
use crate::cache::{Cache, CacheKey, CachedImage, GenerationalCache, ImageMetadata};
use crate::cache::{Cache, CacheKey, CachedImage, ImageMetadata};
use crate::client_api_version;
use crate::config::{SEND_SERVER_VERSION, VALIDATE_TOKENS};
use crate::state::RwLockServerState;
@ -52,7 +52,7 @@ impl Responder for ServerResponse {
#[get("/{token}/data/{chapter_hash}/{file_name}")]
async fn token_data(
state: Data<RwLockServerState>,
cache: Data<Mutex<GenerationalCache>>,
cache: Data<Mutex<Box<dyn Cache>>>,
path: Path<(String, String, String)>,
) -> impl Responder {
let (token, chapter_hash, file_name) = path.into_inner();
@ -68,7 +68,7 @@ async fn token_data(
#[get("/{token}/data-saver/{chapter_hash}/{file_name}")]
async fn token_data_saver(
state: Data<RwLockServerState>,
cache: Data<Mutex<GenerationalCache>>,
cache: Data<Mutex<Box<dyn Cache>>>,
path: Path<(String, String, String)>,
) -> impl Responder {
let (token, chapter_hash, file_name) = path.into_inner();
@ -175,7 +175,7 @@ fn push_headers(builder: &mut HttpResponseBuilder) -> &mut HttpResponseBuilder {
async fn fetch_image(
state: Data<RwLockServerState>,
cache: Data<Mutex<GenerationalCache>>,
cache: Data<Mutex<Box<dyn Cache>>>,
chapter_hash: String,
file_name: String,
is_data_saver: bool,