remove download states map
This commit is contained in:
51
src/main.rs
51
src/main.rs
@@ -1,4 +1,4 @@
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::{
|
||||
body::Bytes,
|
||||
@@ -8,19 +8,10 @@ use axum::{
|
||||
};
|
||||
use image::GenericImageView;
|
||||
use reqwest::StatusCode;
|
||||
use tokio::sync::{Mutex, Notify};
|
||||
use webp::WebPConfig;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Downloader {
|
||||
states: Arc<Mutex<HashMap<String, Arc<DownloadState>>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DownloadState {
|
||||
notify: Notify,
|
||||
result: Mutex<Option<Result<Arc<DownloadData>, (StatusCode, String)>>>,
|
||||
}
|
||||
struct Downloader {}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DownloadData {
|
||||
@@ -30,38 +21,10 @@ struct DownloadData {
|
||||
|
||||
impl Downloader {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
states: Arc::new(Mutex::new(HashMap::new())),
|
||||
}
|
||||
Self {}
|
||||
}
|
||||
|
||||
async fn download(&self, target_url: &str) -> Result<Arc<DownloadData>, (StatusCode, String)> {
|
||||
// check if the url is already downloading
|
||||
{
|
||||
let states = self.states.lock().await;
|
||||
if let Some(state) = states.get(target_url) {
|
||||
// wait for notify
|
||||
state.notify.notified().await;
|
||||
let result = state.result.lock().await;
|
||||
match &*result {
|
||||
Some(Ok(result)) => {
|
||||
return Ok(result.clone());
|
||||
}
|
||||
Some(Err(e)) => return Err(e.clone()),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create a new download state for this url
|
||||
let mut states = self.states.lock().await;
|
||||
let state = Arc::new(DownloadState {
|
||||
notify: Notify::new(),
|
||||
result: Mutex::new(None),
|
||||
});
|
||||
states.insert(target_url.to_string(), state.clone());
|
||||
drop(states);
|
||||
|
||||
let response = reqwest::get(target_url)
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
||||
@@ -84,14 +47,6 @@ impl Downloader {
|
||||
|
||||
let download_data = Arc::new(DownloadData { body, headers });
|
||||
|
||||
// notify all waiters
|
||||
{
|
||||
let mut states = self.states.lock().await;
|
||||
let state = states.remove(target_url).unwrap();
|
||||
state.result.lock().await.replace(Ok(download_data.clone()));
|
||||
state.notify.notify_waiters();
|
||||
}
|
||||
|
||||
Ok(download_data.into())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user