From 3dbf5ab5737857f961b7b6e17cc01ffc7c801e25 Mon Sep 17 00:00:00 2001 From: DecDuck Date: Tue, 12 Nov 2024 09:06:28 +1100 Subject: [PATCH] chore(downloads): partial download manager --- src-tauri/src/downloads/download_agent.rs | 9 +++-- src-tauri/src/downloads/download_commands.rs | 13 +++++-- src-tauri/src/downloads/download_manager.rs | 40 ++++++++++++++++++++ src-tauri/src/downloads/mod.rs | 1 + src-tauri/src/lib.rs | 14 ++++--- 5 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 src-tauri/src/downloads/download_manager.rs diff --git a/src-tauri/src/downloads/download_agent.rs b/src-tauri/src/downloads/download_agent.rs index a46eceb..8bcd2b5 100644 --- a/src-tauri/src/downloads/download_agent.rs +++ b/src-tauri/src/downloads/download_agent.rs @@ -4,11 +4,13 @@ use crate::downloads::manifest::{DropDownloadContext, DropManifest}; use crate::remote::RemoteAccessError; use crate::DB; use log::info; -use rayon::ThreadPoolBuilder; +use rayon::{spawn, ThreadPool, ThreadPoolBuilder}; use std::fmt::{Display, Formatter}; use std::fs::{create_dir_all, File}; use std::path::Path; -use std::sync::Mutex; +use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; +use std::sync::{Arc, Mutex}; +use std::thread::Thread; use urlencoding::encode; #[cfg(target_os = "linux")] @@ -207,6 +209,7 @@ impl GameDownloadAgent { .build() .unwrap(); + pool.scope(move |scope| { let contexts = self.contexts.lock().unwrap(); @@ -223,6 +226,6 @@ impl GameDownloadAgent { download_game_chunk(context, control_flag, progress).unwrap(); }); } - }) + }); } } diff --git a/src-tauri/src/downloads/download_commands.rs b/src-tauri/src/downloads/download_commands.rs index 54b9315..9449ab2 100644 --- a/src-tauri/src/downloads/download_commands.rs +++ b/src-tauri/src/downloads/download_commands.rs @@ -11,6 +11,7 @@ pub fn download_game( game_version: String, state: tauri::State<'_, Mutex>, ) -> Result<(), String> { + /* info!("beginning game download..."); let mut download_agent = GameDownloadAgent::new(game_id.clone(), game_version.clone(), 0); @@ -19,7 +20,7 @@ pub fn download_game( let mut lock: std::sync::MutexGuard<'_, AppState> = state.lock().unwrap(); let download_agent_ref = Arc::new(download_agent); - lock.game_downloads + lock.download_manager .insert(game_id, download_agent_ref.clone()); // Run it in another thread @@ -27,6 +28,7 @@ pub fn download_game( // Run doesn't require mutable download_agent_ref.clone().run(); }); + */ Ok(()) } @@ -36,18 +38,23 @@ pub fn get_game_download_progress( state: tauri::State<'_, Mutex>, game_id: String, ) -> Result { + /* let download_agent = use_download_agent(state, game_id)?; let progress = &download_agent.progress; Ok(progress.get_progress()) -} + */ + Ok(0.0) +} +/* fn use_download_agent( state: tauri::State<'_, Mutex>, game_id: String, ) -> Result, String> { let lock = state.lock().unwrap(); - let download_agent = lock.game_downloads.get(&game_id).ok_or("Invalid game ID")?; + let download_agent = lock.download_manager.get(&game_id).ok_or("Invalid game ID")?; Ok(download_agent.clone()) // Clones the Arc, not the underlying data structure } +*/ \ No newline at end of file diff --git a/src-tauri/src/downloads/download_manager.rs b/src-tauri/src/downloads/download_manager.rs new file mode 100644 index 0000000..3c14fa8 --- /dev/null +++ b/src-tauri/src/downloads/download_manager.rs @@ -0,0 +1,40 @@ +use std::{ + collections::HashMap, + sync::{Arc, Mutex}, + thread::JoinHandle, +}; + +use super::{download_agent::GameDownloadAgent, download_thread_control_flag::DownloadThreadControlFlag}; + +pub struct DownloadManager { + download_agent_registry: HashMap>>, + download_queue: Vec, + + current_thread: Option>, + current_game_id: Option, // Should be the only game download agent in the map with the "Go" flag +} + +impl DownloadManager { + pub fn new() -> Self { + return Self { + download_agent_registry: HashMap::new(), + download_queue: Vec::new(), + current_thread: None, + current_game_id: None, + }; + } + + pub fn queue_game(&mut self, game_id: String, version_name: String) { + let existing_da = self.download_agent_registry.get(&game_id); + + if let Some(da_mutex) = existing_da { + let da = da_mutex.lock().unwrap(); + if da.version == version_name { + return; // We're already queued + } + + da.control_flag.set(DownloadThreadControlFlag::Stop); + + } + } +} diff --git a/src-tauri/src/downloads/mod.rs b/src-tauri/src/downloads/mod.rs index d4ade96..ea2edfd 100644 --- a/src-tauri/src/downloads/mod.rs +++ b/src-tauri/src/downloads/mod.rs @@ -1,5 +1,6 @@ pub mod download_agent; pub mod download_commands; +pub mod download_manager; mod download_logic; mod download_thread_control_flag; mod manifest; diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index bef2fab..5e880a2 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -13,6 +13,7 @@ use crate::downloads::download_agent::GameDownloadAgent; use auth::{auth_initiate, generate_authorization_header, recieve_handshake}; use db::{add_new_download_dir, DatabaseInterface, DATA_ROOT_DIR}; use downloads::download_commands::*; +use downloads::download_manager::DownloadManager; use env_logger::Env; use http::{header::*, response::Builder as ResponseBuilder}; use library::{fetch_game, fetch_library, Game}; @@ -53,7 +54,7 @@ pub struct AppState { games: HashMap, #[serde(skip_serializing)] - game_downloads: HashMap>, + download_manager: Arc, } #[tauri::command] @@ -67,13 +68,16 @@ fn fetch_state(state: tauri::State<'_, Mutex>) -> Result AppState { env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); + let games = HashMap::new(); + let download_manager = Arc::new(DownloadManager::new()); + let is_set_up = DB.database_is_set_up(); if !is_set_up { return AppState { status: AppStatus::NotConfigured, user: None, - games: HashMap::new(), - game_downloads: HashMap::new(), + games, + download_manager, }; } @@ -81,8 +85,8 @@ fn setup() -> AppState { AppState { status: app_status, user, - games: HashMap::new(), - game_downloads: HashMap::new(), + games, + download_manager, } }