Skip to content

Commit 415a670

Browse files
committed
add cache for file reader
1 parent d678c3d commit 415a670

File tree

1 file changed

+50
-12
lines changed

1 file changed

+50
-12
lines changed

src/restapi.rs

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,43 @@
11
use crate::utils::DisplayVec;
22
use goose::goose::{GooseUser, TransactionError, TransactionResult};
33
use serde_json::json;
4+
use std::collections::HashMap;
45
use std::sync::{
56
Arc,
67
atomic::{AtomicUsize, Ordering},
78
};
9+
use tokio::sync::{OnceCell, RwLock};
810
use urlencoding::encode;
911

12+
/// Cache for advisory files
13+
static FILE_CACHE: OnceCell<RwLock<HashMap<String, Vec<u8>>>> = OnceCell::const_new();
14+
15+
/// Get advisory file cache
16+
async fn get_file_cache() -> &'static RwLock<HashMap<String, Vec<u8>>> {
17+
FILE_CACHE
18+
.get_or_init(|| async { RwLock::new(HashMap::new()) })
19+
.await
20+
}
21+
22+
/// Upload advisory data and extract advisory ID from response
23+
async fn upload_advisory_and_extract_id(
24+
file_bytes: Vec<u8>,
25+
user: &mut GooseUser,
26+
) -> Result<String, Box<TransactionError>> {
27+
let response = user.post("/api/v2/advisory", file_bytes).await?;
28+
let v = response.response?.json::<serde_json::Value>().await?;
29+
let advisory_id = v["id"]
30+
.as_str()
31+
.ok_or_else(|| {
32+
Box::new(TransactionError::Custom(
33+
"Missing advisory ID in response".to_string(),
34+
))
35+
})?
36+
.to_string();
37+
38+
Ok(advisory_id)
39+
}
40+
1041
pub async fn get_advisory(id: String, user: &mut GooseUser) -> TransactionResult {
1142
let uri = format!("/api/v2/advisory/{}", encode(&format!("urn:uuid:{}", id)));
1243

@@ -43,26 +74,33 @@ pub async fn upload_advisory_and_get_id(
4374
advisory_file: String,
4475
user: &mut GooseUser,
4576
) -> Result<String, Box<TransactionError>> {
77+
// Check cache first
78+
let cache = get_file_cache().await;
79+
80+
{
81+
let read_guard = cache.read().await;
82+
if let Some(cached_bytes) = read_guard.get(&advisory_file) {
83+
let file_bytes = cached_bytes.clone();
84+
// Found in cache, upload directly
85+
drop(read_guard);
86+
87+
return upload_advisory_and_extract_id(file_bytes, user).await;
88+
}
89+
}
90+
4691
let file_bytes = tokio::fs::read(&advisory_file).await.map_err(|e| {
4792
Box::new(TransactionError::Custom(format!(
4893
"Failed to read file {}: {}",
4994
advisory_file, e
5095
)))
5196
})?;
5297

53-
let response = user.post("/api/v2/advisory", file_bytes).await?;
54-
let v = response.response?.json::<serde_json::Value>().await?;
55-
56-
let advisory_id = v["id"]
57-
.as_str()
58-
.ok_or_else(|| {
59-
Box::new(TransactionError::Custom(
60-
"Missing advisory ID in response".to_string(),
61-
))
62-
})?
63-
.to_string();
98+
{
99+
let mut write_guard = cache.write().await;
100+
write_guard.insert(advisory_file.clone(), file_bytes.clone());
101+
}
64102

65-
Ok(advisory_id)
103+
upload_advisory_and_extract_id(file_bytes, user).await
66104
}
67105

68106
/// Delete advisory by ID

0 commit comments

Comments
 (0)