feat: implement parallel downloads

Signed-off-by: Tomkoid <tomaszierl@outlook.com>
This commit is contained in:
Tomkoid 2024-03-24 18:14:05 +01:00
parent 04ec04a05b
commit 71da93a681
No known key found for this signature in database
GPG key ID: D4403E79602EE85B
6 changed files with 137 additions and 34 deletions

78
Cargo.lock generated
View file

@ -32,7 +32,7 @@ version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"hermit-abi 0.1.19",
"libc",
"winapi",
]
@ -371,6 +371,12 @@ dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "http"
version = "0.2.12"
@ -522,6 +528,16 @@ version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.21"
@ -607,6 +623,16 @@ dependencies = [
"pin-utils",
]
[[package]]
name = "num_cpus"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
"hermit-abi 0.3.9",
"libc",
]
[[package]]
name = "object"
version = "0.32.2"
@ -672,6 +698,29 @@ version = "6.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1"
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets 0.48.5",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
@ -877,6 +926,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "security-framework"
version = "2.9.2"
@ -971,6 +1026,12 @@ dependencies = [
"autocfg",
]
[[package]]
name = "smallvec"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
[[package]]
name = "socket2"
version = "0.5.6"
@ -1141,11 +1202,26 @@ dependencies = [
"bytes",
"libc",
"mio",
"num_cpus",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys 0.48.0",
]
[[package]]
name = "tokio-macros"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.1"

View file

@ -26,7 +26,7 @@ regex = "1.7.0"
reqwest = { version = "0.11.11", features = ["blocking", "socks"] }
serde = { version = "1.0.147", features = ["derive"] }
spinners = "4.1.0"
tokio = "1.36.0"
tokio = { version = "1.36.0", features = ["rt", "full"] }
toml = "0.5.9"
[target.'cfg(unix)'.dependencies]

View file

@ -1,11 +1,12 @@
use std::sync::Arc;
use crate::AppState;
use super::*;
pub fn sync_repositories(app_state: &AppState) {
pub async fn sync_repositories(app_state: &AppState) {
let colors = &app_state.colors;
let messages = &app_state.messages;
let args = &app_state.args;
// Sync all repositories
let repos_file_location = format!("{}/repos", get_data_dir());
@ -29,41 +30,42 @@ pub fn sync_repositories(app_state: &AppState) {
);
std::process::exit(1);
}
println!(
"{}{}{} {}{}",
colors.bold_blue,
messages.message.get("syncing").unwrap(),
colors.reset,
colors.green,
colors.reset
);
let mut thread_joins: Vec<tokio::task::JoinHandle<String>> = Vec::new();
for repo in repos.lines() {
if repo.is_empty() {
continue;
}
// print!(
// " [{}*{}] {} {}.. ",
// colors.bold_blue,
// colors.reset,
// messages.message.get("syncing").unwrap(),
// repo,
// );
let repo = repo.to_string();
let mut syncing_spinner = Spinner::new(
SPINNER_TYPE,
format!(
"{}{}{} {}{}{}",
colors.bold_blue,
messages.message.get("syncing").unwrap(),
colors.reset,
colors.green,
repo,
colors.reset
),
);
let app_state_cloned = app_state.clone();
std::io::stdout().flush().unwrap();
let thread_handle = tokio::task::spawn_blocking(move || sync_repo(repo, &app_state_cloned));
let error = sync(repo, &args);
thread_joins.push(thread_handle);
}
if !error {
syncing_spinner.stop_with_newline();
} else {
println!("{}error{}", colors.bold_red, colors.reset);
for thread_join in thread_joins {
let thread_join = thread_join.await;
if thread_join.is_err() {
eprintln!(" {}> error{}", colors.bold_red, colors.reset);
}
let result = thread_join.unwrap();
println!(" {}>{} {}", colors.bold_green, colors.reset, result);
}
let changed = local_hosts_output != read_file_to_string(&local_hosts).unwrap();
@ -82,3 +84,26 @@ pub fn sync_repositories(app_state: &AppState) {
exit(0);
}
fn sync_repo(repo: String, app_state: &AppState) -> String {
// print!(
// " [{}*{}] {} {}.. ",
// colors.bold_blue,
// colors.reset,
// messages.message.get("syncing").unwrap(),
// repo,
// );
std::io::stdout().flush().unwrap();
let error = sync(&repo, &app_state.args);
if error {
eprintln!(
" {}> error{}",
app_state.colors.bold_red, app_state.colors.reset
);
}
repo
}

View file

@ -12,11 +12,11 @@ use crate::{
use crate::actions::sync::sync_repositories;
pub fn exec_command(app_state: &AppState) {
pub async fn exec_command(app_state: &AppState) {
let args = &app_state.args;
match args.to_owned().command {
Commands::Sync(_) => sync_repositories(&app_state),
Commands::Sync(_) => sync_repositories(&app_state).await,
Commands::Apply => apply_hosts(&app_state),
Commands::ApplyAndroid(a) => apply_android_action(&app_state, a.device),
Commands::Backup => backup(&app_state),

View file

@ -60,6 +60,7 @@ pub enum Actions {
Apply,
}
#[derive(Clone)]
pub struct AppState {
pub args: Args,
pub logger: Logger,
@ -67,7 +68,8 @@ pub struct AppState {
pub messages: Messages,
}
fn main() {
#[tokio::main]
async fn main() {
// Initialize colors
let colors = Colors::new();
@ -96,7 +98,7 @@ fn main() {
initialize_dir();
}
exec_command(&state);
exec_command(&state).await;
// Check if allowed exit functions ended (else exit)
check_allowed_function(&args);

View file

@ -16,7 +16,7 @@ adblocker_started_no_networkmanager = "Successfully modified the hosts file, but
synced_successfully = "Synced all repos successfully."
nothing_changed = "Nothing changed."
no_action_specified = "No action specified."
syncing = "Synchronizing"
syncing = "Synchronizing repositories.."
no_repos_to_sync = "There are no repos to sync."
permission_denied = "Permission Denied"
unknown_error = "Error occurred"