Skip to content

Commit eb3cd33

Browse files
Limit parallel network requests to a default of 10, and allow configuring it via a command line flag
1 parent 48531ac commit eb3cd33

File tree

6 files changed

+35
-19
lines changed

6 files changed

+35
-19
lines changed

Cargo.lock

Lines changed: 11 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ tokio = { version = "1.40", default-features = false, features = [
5252
"rt-multi-thread",
5353
"macros",
5454
] }
55+
rustls = { version = "0.23", features = ["ring"] }
5556
clap = { version = "4.5", features = ["derive"] }
5657
clap_complete = "4.5"
5758
serde_json = "1.0"

src/cli.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ pub struct Ferium {
1515
/// You can also use the environment variable `TOKIO_WORKER_THREADS`.
1616
#[clap(long, short)]
1717
pub threads: Option<usize>,
18+
/// Specify the maximum number of parallel network requests to perform.
19+
#[clap(long, short = 'p')]
20+
pub parallel_network: Option<usize>,
1821
/// Set a GitHub personal access token for increasing the GitHub API rate limit.
1922
/// You can also use the environment variable `GITHUB_TOKEN`.
2023
#[clap(long, visible_alias = "gh")]

src/download.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![expect(clippy::expect_used, reason = "For mutex poisons")]
22

3-
use crate::{STYLE_BYTE, TICK};
3+
use crate::{DEFAULT_PARALLEL_NETWORK, PARALLEL_NETWORK, STYLE_BYTE, TICK};
44
use anyhow::{anyhow, bail, Error, Result};
55
use colored::Colorize as _;
66
use fs_extra::{
@@ -19,8 +19,6 @@ use std::{
1919
};
2020
use tokio::sync::Semaphore;
2121

22-
const CONCURRENT_DOWNLOADS: usize = 6;
23-
2422
/// Check the given `directory`
2523
///
2624
/// - If there are files there that are not in `to_download` or `to_install`, they will be moved to `directory`/.old
@@ -115,7 +113,9 @@ pub async fn download(
115113
.expect("Mutex poisoned")
116114
.enable_steady_tick(Duration::from_millis(100));
117115
let mut tasks = FuturesUnordered::new();
118-
let semaphore = Arc::new(Semaphore::new(CONCURRENT_DOWNLOADS));
116+
let semaphore = Arc::new(Semaphore::new(
117+
*PARALLEL_NETWORK.get_or_init(|| DEFAULT_PARALLEL_NETWORK),
118+
));
119119
let client = reqwest::Client::new();
120120

121121
for downloadable in to_download {
@@ -126,6 +126,7 @@ pub async fn download(
126126

127127
tasks.push(async move {
128128
let _permit = semaphore.acquire_owned().await?;
129+
129130
let (length, filename) = downloadable
130131
.download(&client, &output_dir, |additional| {
131132
progress_bar

src/main.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,15 @@ use libium::{
3838
use std::{
3939
env::{set_var, var_os},
4040
process::ExitCode,
41-
sync::LazyLock,
41+
sync::{LazyLock, OnceLock},
4242
};
4343

4444
const CROSS: &str = "×";
4545
static TICK: LazyLock<ColoredString> = LazyLock::new(|| "✓".green());
4646

47+
pub static PARALLEL_NETWORK: OnceLock<usize> = OnceLock::new();
48+
pub const DEFAULT_PARALLEL_NETWORK: usize = 10;
49+
4750
/// Indicatif themes
4851
#[expect(clippy::expect_used)]
4952
pub static STYLE_NO: LazyLock<ProgressStyle> = LazyLock::new(|| {
@@ -72,6 +75,8 @@ fn main() -> ExitCode {
7275

7376
let cli = Ferium::parse();
7477

78+
let _ = rustls::crypto::ring::default_provider().install_default();
79+
7580
let mut builder = tokio::runtime::Builder::new_multi_thread();
7681
builder.enable_all();
7782
builder.thread_name("ferium-worker");
@@ -138,6 +143,9 @@ async fn actual_main(mut cli_app: Ferium) -> Result<()> {
138143
if let Some(key) = cli_app.curseforge_api_key {
139144
set_var("CURSEFORGE_API_KEY", key);
140145
}
146+
if let Some(n) = cli_app.parallel_network {
147+
let _ = PARALLEL_NETWORK.set(n);
148+
}
141149

142150
let mut config_file = config::get_file(
143151
&cli_app

src/subcommands/upgrade.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use crate::{
44
download::{clean, download},
5-
CROSS, STYLE_NO, TICK,
5+
CROSS, DEFAULT_PARALLEL_NETWORK, PARALLEL_NETWORK, STYLE_NO, TICK,
66
};
77
use anyhow::{anyhow, bail, Result};
88
use colored::Colorize as _;
@@ -34,7 +34,9 @@ pub async fn get_platform_downloadables(profile: &Profile) -> Result<(Vec<Downlo
3434
let mut tasks = FuturesUnordered::new();
3535

3636
println!("{}\n", "Determining the Latest Compatible Versions".bold());
37-
let semaphore = Arc::new(Semaphore::new(75));
37+
let semaphore = Arc::new(Semaphore::new(
38+
*PARALLEL_NETWORK.get_or_init(|| DEFAULT_PARALLEL_NETWORK),
39+
));
3840
progress_bar
3941
.lock()
4042
.expect("Mutex poisoned")
@@ -47,12 +49,12 @@ pub async fn get_platform_downloadables(profile: &Profile) -> Result<(Vec<Downlo
4749
.unwrap_or(20)
4850
.clamp(20, 50);
4951
for mod_ in profile.mods.clone() {
50-
let permit = Arc::clone(&semaphore).acquire_owned().await?;
52+
let semaphore = Arc::clone(&semaphore);
5153
let to_download = Arc::clone(&to_download);
5254
let progress_bar = Arc::clone(&progress_bar);
5355

5456
tasks.push(async move {
55-
let _permit = permit;
57+
let _permit = semaphore.acquire_owned().await?;
5658
let result = mod_.fetch_download_file(profile.filters.clone()).await;
5759
let progress_bar = progress_bar.lock().expect("Mutex poisoned");
5860
progress_bar.inc(1);

0 commit comments

Comments
 (0)