Skip to content

Commit

Permalink
Fix simultaneous downloads (#433)
Browse files Browse the repository at this point in the history
Acquire a semaphore permit while executing each download task, instead
of while _creating_ each download task.
- Fixes #370
- Prevents deadlocking when downloading more than 75 mods
- Aet reasonable number of concurrent downloads
- Don't wrap `request::Client` in an `Arc`
	`request::Client` is just an `Arc` wrapper around its own internal type anyway.
  • Loading branch information
thomhayward authored Oct 2, 2024
1 parent e034941 commit 48531ac
Showing 1 changed file with 7 additions and 5 deletions.
12 changes: 7 additions & 5 deletions src/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ use std::{
};
use tokio::sync::Semaphore;

const CONCURRENT_DOWNLOADS: usize = 6;

/// Check the given `directory`
///
/// - If there are files there that are not in `to_download` or `to_install`, they will be moved to `directory`/.old
Expand Down Expand Up @@ -113,17 +115,17 @@ pub async fn download(
.expect("Mutex poisoned")
.enable_steady_tick(Duration::from_millis(100));
let mut tasks = FuturesUnordered::new();
let semaphore = Arc::new(Semaphore::new(75));
let client = Arc::new(reqwest::Client::new());
let semaphore = Arc::new(Semaphore::new(CONCURRENT_DOWNLOADS));
let client = reqwest::Client::new();

for downloadable in to_download {
let permit = Arc::clone(&semaphore).acquire_owned().await?;
let semaphore = Arc::clone(&semaphore);
let progress_bar = Arc::clone(&progress_bar);
let client = Arc::clone(&client);
let client = client.clone();
let output_dir = output_dir.clone();

tasks.push(async move {
let _permit = permit;
let _permit = semaphore.acquire_owned().await?;
let (length, filename) = downloadable
.download(&client, &output_dir, |additional| {
progress_bar
Expand Down

0 comments on commit 48531ac

Please sign in to comment.