Skip to content

Commit b2b1985

Browse files
committed
move cache to ram, fix cache poiter scoup
1 parent 7b24eda commit b2b1985

File tree

11 files changed

+139
-79
lines changed

11 files changed

+139
-79
lines changed

.cache/AmongUsBlack.png

-3.18 KB
Binary file not shown.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ regex = "1.12.2"
2323
rayon = "1.11.0"
2424
dotenvy = "0.15.7"
2525
futures = "0.3.31"
26+
bytes = "1.10.1"
2627

2728
[dev-dependencies]
2829
tokio = { version = "1.48.0", features = ["full"] }

src/app.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
//! - Мб рейтлимит
2121
//! - Бан лист (:))
2222
23+
pub mod cache;
2324
pub mod lock;
2425
pub mod logger;
2526
pub mod png;
@@ -48,14 +49,14 @@ async fn doc() -> Html {
4849
Html(fs::read_to_string(DOC_HTML_PATH).await.expect("wtf"))
4950
}
5051

51-
pub struct AppState<'a> {
52+
pub struct AppState {
5253
pub lock: Lock,
53-
pub cache: Cache<'a>,
54+
pub cache: Cache,
5455
}
5556

5657
pub async fn app(
5758
lock: Lock,
58-
cache: Cache<'static>,
59+
cache: Cache,
5960
) {
6061
let router = Ohkami::new((
6162
Context::new(Arc::new(AppState {

src/app/cache.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use std::sync::Arc;
2+
3+
use ohkami::{IntoResponse, Json, fang::Context};
4+
use tracing::debug;
5+
6+
use crate::{app::AppState, error::Error};
7+
8+
#[inline(always)]
9+
/// Represent GET method to return list of skins
10+
pub async fn cache_handler<'a>(
11+
Context(state): Context<'a, Arc<AppState>>
12+
) -> Result<impl IntoResponse + 'a, Error> {
13+
Ok(Json(
14+
state
15+
.cache
16+
.store
17+
.iter()
18+
.map(|x| {
19+
let key = x.key().clone();
20+
debug!(key=?key);
21+
key
22+
})
23+
.collect::<Vec<_>>(),
24+
))
25+
}

src/app/lock.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ use crate::{app::AppState, error::Error};
77
#[inline(always)]
88
/// Represent GET method to return list of skins
99
pub async fn lock_handler<'a>(
10-
Context(state): Context<'a, Arc<AppState<'a>>>
10+
Context(state): Context<'a, Arc<AppState>>
1111
) -> Result<impl IntoResponse + 'a, Error> {
12-
Ok(Json(serde_json::to_string_pretty::<Vec<String>>(
12+
Ok(Json(
1313
state
1414
.lock
1515
.store
1616
.iter()
1717
.map(|x| x.key().to_string())
18-
.collect::<Vec<_>>()
19-
.as_ref(),
20-
)?))
18+
.collect::<Vec<_>>(),
19+
))
2120
}

src/app/skin.rs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::sync::Arc;
1+
use std::{fmt::Display, sync::Arc};
22

33
use ohkami::{
44
IntoResponse, Ohkami, Query, Route,
@@ -7,9 +7,11 @@ use ohkami::{
77
openapi::{self, Schema},
88
serde::Deserialize,
99
};
10+
use serde::Serialize;
11+
use tracing::instrument;
1012

1113
use crate::{
12-
app::{AppState, lock::lock_handler, logger::LogRequest, png::Png},
14+
app::{AppState, cache::cache_handler, lock::lock_handler, logger::LogRequest, png::Png},
1315
error::Error,
1416
};
1517

@@ -20,26 +22,40 @@ pub fn skin_router() -> Ohkami {
2022
openapi::Tag("skin"),
2123
"/".GET(skin_handler),
2224
"/store".GET(lock_handler),
25+
"/cache".GET(cache_handler),
2326
))
2427
}
2528

26-
#[derive(Debug, Clone, Copy, Deserialize, Schema, Hash, PartialEq, Eq)]
29+
#[derive(Debug, Clone, Deserialize, Schema, Hash, PartialEq, Eq, Serialize)]
2730
/// Params for expose Tee
28-
pub struct SkinQuery<'req> {
29-
pub name: &'req str,
31+
pub struct SkinQuery {
32+
pub name: String,
3033
pub body: Option<u32>,
3134
pub feet: Option<u32>,
3235
}
3336

37+
impl Display for SkinQuery {
38+
fn fmt(
39+
&self,
40+
f: &mut std::fmt::Formatter<'_>,
41+
) -> std::fmt::Result {
42+
f.debug_struct("SkinQuery")
43+
.field("name", &self.name)
44+
.field("body", &self.body)
45+
.field("feet", &self.feet)
46+
.finish()
47+
}
48+
}
49+
3450
#[inline(always)]
51+
#[instrument(skip(state))]
3552
/// Represent GET method to return a builded skin by query
3653
async fn skin_handler<'a>(
37-
Context(state): Context<'a, Arc<AppState<'a>>>,
38-
// Context(cache): Context<'a, Cache<'a>>,
39-
Query(query): Query<SkinQuery<'a>>,
40-
) -> Result<impl IntoResponse + 'a, Error> {
41-
Ok(Created(Png(match state.cache.get(query).await {
42-
Ok(Some(e)) => e,
54+
Context(state): Context<'a, Arc<AppState>>,
55+
Query(query): Query<SkinQuery>,
56+
) -> Result<impl IntoResponse, Error> {
57+
Ok(Created(Png(match state.cache.get(&query).await {
58+
Ok(Some(e)) => e.to_vec(),
4359
_ => state.lock.get(state.cache.clone(), query).await?,
4460
})))
4561
}

src/cache.rs

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@
99
//! В коде храним DashMap с <(name,Option<body_color>, Option<feet_color>): Path (absolut)>
1010
1111
use std::{
12-
path::{Path, PathBuf},
1312
sync::Arc,
1413
time::{Duration, Instant},
1514
};
1615

16+
use bytes::Bytes;
1717
use dashmap::DashMap;
18-
use tokio::fs;
19-
use tracing::{info, instrument};
18+
use tracing::info;
2019

2120
pub const FIVE_MINUTES: Duration = Duration::from_secs(900);
2221

@@ -25,15 +24,15 @@ use crate::{app::skin::SkinQuery, error::Error};
2524
pub struct CacheItem {
2625
/// Then it be placed to cache
2726
pub timestamp: Instant,
28-
/// It is't relative, it absolute path
29-
pub path: String,
27+
/// `Tee`'s data
28+
pub data: Bytes,
3029
}
3130

3231
impl CacheItem {
33-
pub fn new(path_to_skin: String) -> Self {
32+
pub fn new(data: Bytes) -> Self {
3433
Self {
3534
timestamp: Instant::now(),
36-
path: path_to_skin,
35+
data,
3736
}
3837
}
3938

@@ -43,48 +42,35 @@ impl CacheItem {
4342
}
4443
}
4544
#[derive(Debug)]
46-
pub struct CacheStore<'a> {
47-
pub path: PathBuf,
48-
pub store: DashMap<SkinQuery<'a>, CacheItem>,
45+
pub struct CacheStore {
46+
pub store: DashMap<SkinQuery, CacheItem>,
4947
}
5048

51-
impl<'a, 'b: 'a> CacheStore<'a> {
52-
pub async fn new(path: impl AsRef<Path>) -> Self {
53-
fs::create_dir(path.as_ref()).await.ok();
49+
impl CacheStore {
50+
pub async fn new() -> Self {
5451
Self {
55-
path: path.as_ref().to_path_buf(),
5652
store: DashMap::default(),
5753
}
5854
}
5955

6056
pub async fn save(
6157
&self,
62-
query: SkinQuery<'b>,
63-
data: &[u8],
58+
query: SkinQuery,
59+
data: Bytes,
6460
) -> Result<(), Error> {
65-
let path = self
66-
.path
67-
.to_path_buf()
68-
.join(query.name)
69-
.with_extension("png");
70-
fs::write(&path, data).await?;
71-
self.store.insert(
72-
query,
73-
CacheItem::new(path.canonicalize()?.display().to_string()),
74-
);
61+
self.store.insert(query, CacheItem::new(data));
7562
Ok(())
7663
}
7764

78-
#[instrument(skip(self))]
7965
pub async fn get(
8066
&self,
81-
query: SkinQuery<'b>,
82-
) -> Result<Option<Vec<u8>>, Error> {
67+
query: &SkinQuery,
68+
) -> Result<Option<Bytes>, Error> {
8369
match self.store.get(&query) {
8470
Some(x) => {
8571
if x.value().is_acutal() {
86-
info!("Take from cache");
87-
Ok(Some(fs::read(&x.value().path).await?))
72+
info!(query=%query, "Take from cache");
73+
Ok(Some(x.value().data.clone()))
8874
} else {
8975
Ok(None)
9076
}
@@ -93,4 +79,4 @@ impl<'a, 'b: 'a> CacheStore<'a> {
9379
}
9480
}
9581
}
96-
pub type Cache<'a> = Arc<CacheStore<'a>>;
82+
pub type Cache = Arc<CacheStore>;

src/main.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{sync::Arc, time::Duration};
22

33
use tokio::{fs, time::sleep};
4-
use tracing::{Level, error, info};
4+
use tracing::{Level, info};
55

66
use crate::{
77
app::app,
@@ -41,9 +41,7 @@ async fn main() {
4141
.await
4242
.unwrap(),
4343
);
44-
let cache = Arc::new(
45-
CacheStore::new(std::env::var("CACHE_PATH").expect("CACHE_PATH must be set")).await,
46-
);
44+
let cache = Arc::new(CacheStore::new().await);
4745

4846
fs::create_dir("static").await.ok();
4947

@@ -75,14 +73,8 @@ async fn main() {
7573
.collect();
7674

7775
for key in keys {
78-
if let Some(cached) = cache.store.get(&key) {
79-
if let Err(e) = fs::remove_file(&cached.path).await {
80-
error!(name=%key.name,body=?key.body, feet=?key.feet,path=?cached.path,"Delete failed: {e}" );
81-
} else {
82-
info!(name=%key.name, body=?key.body, feet=?key.feet, "Item has removed from cache");
83-
cache.store.remove(&key);
84-
}
85-
}
76+
info!(name=%key.name, body=?key.body, feet=?key.feet, "Item has removed from cache");
77+
cache.store.remove(&key);
8678
}
8779
tracing::info!("Cache cleared");
8880
}

src/rsync.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,18 @@ pub async fn try_sync_skins(lock: Arc<LockStore>) -> Result<(), Error> {
5454
.into_par_iter()
5555
.flat_map_iter(|v| v.into_iter())
5656
.fold(
57-
|| HashMap::new(),
57+
HashMap::new,
5858
|mut acc: HashMap<String, SkinMeta>, skin: SkinMeta| {
5959
acc.entry(skin.name.to_string()).or_insert(skin);
6060
acc
6161
},
6262
)
63-
.reduce(
64-
|| HashMap::new(),
65-
|mut a, b| {
66-
for (k, v) in b {
67-
a.entry(k).or_insert(v);
68-
}
69-
a
70-
},
71-
)
63+
.reduce(HashMap::new, |mut a, b| {
64+
for (k, v) in b {
65+
a.entry(k).or_insert(v);
66+
}
67+
a
68+
})
7269
})
7370
.await?;
7471

src/rsync/lock.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,15 @@ impl LockStore {
177177
}
178178

179179
/// Return [Tee] by [SkinQuery] and cache reuslt to the [Cache]
180-
pub async fn get<'a: 'b, 'b>(
180+
pub async fn get(
181181
&self,
182-
cache: Cache<'b>,
183-
query: SkinQuery<'a>,
182+
cache: Cache,
183+
query: SkinQuery,
184184
) -> Result<Vec<u8>, Error> {
185185
let uv = fs::read(
186186
&self
187187
.store
188-
.get(query.name)
188+
.get(&query.name)
189189
.ok_or(Error::QueryNameNotFound)?
190190
.value()
191191
.path,
@@ -213,7 +213,7 @@ impl LockStore {
213213
},
214214
)
215215
.await???;
216-
cache.save(query, &tee).await?;
216+
cache.save(query.clone(), tee.clone()).await?;
217217
Ok(tee.to_vec())
218218
}
219219
}

0 commit comments

Comments
 (0)