Skip to content

Commit 93f18f5

Browse files
Limit concurrent fetches to one per repo (#1073)
Concurrent fetches for the same repo used to cause races and errors when updating refs. Change: one-fetch-per-repo
1 parent 93ad8f5 commit 93f18f5

File tree

3 files changed

+13
-12
lines changed

3 files changed

+13
-12
lines changed

josh-proxy/src/bin/josh-proxy.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ struct JoshProxyService {
8484
upstream: JoshProxyUpstream,
8585
fetch_timers: Arc<RwLock<FetchTimers>>,
8686
heads_map: HeadsMap,
87-
fetch_permits: Arc<tokio::sync::Semaphore>,
87+
fetch_permits: Arc<std::sync::Mutex<HashMap<String, Arc<tokio::sync::Semaphore>>>>,
8888
filter_permits: Arc<tokio::sync::Semaphore>,
8989
poll: Polls,
9090
}
@@ -169,7 +169,13 @@ async fn fetch_upstream(
169169
let span = tracing::span!(tracing::Level::TRACE, "fetch worker");
170170
let us = upstream_repo.clone();
171171
let ru = remote_url.clone();
172-
let permit = service.fetch_permits.acquire().await;
172+
let semaphore = service
173+
.fetch_permits
174+
.lock()?
175+
.entry(us.clone())
176+
.or_insert(Arc::new(tokio::sync::Semaphore::new(1)))
177+
.clone();
178+
let permit = semaphore.acquire().await;
173179
let task_remote_auth = remote_auth.clone();
174180
let fetch_result = tokio::task::spawn_blocking(move || {
175181
let _span_guard = span.enter();
@@ -1282,7 +1288,7 @@ async fn run_proxy() -> josh::JoshResult<i32> {
12821288
fetch_timers: Arc::new(RwLock::new(FetchTimers::new())),
12831289
heads_map: Arc::new(RwLock::new(std::collections::HashMap::new())),
12841290
poll: Arc::new(std::sync::Mutex::new(std::collections::HashSet::new())),
1285-
fetch_permits: Arc::new(tokio::sync::Semaphore::new(ARGS.concurrent_n)),
1291+
fetch_permits: Default::default(),
12861292
filter_permits: Arc::new(tokio::sync::Semaphore::new(10)),
12871293
});
12881294

josh-proxy/src/cli.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ pub struct Args {
1212
pub gc: bool,
1313
pub require_auth: bool,
1414
pub no_background: bool,
15-
pub concurrent_n: usize,
1615
pub port: u16,
1716
pub cache_duration: u64,
1817
pub static_resource_proxy_target: Option<String>,
@@ -68,11 +67,9 @@ fn make_command() -> clap::Command {
6867
.long("no-background")
6968
.action(clap::ArgAction::SetTrue),
7069
)
71-
.arg(
72-
clap::Arg::new("n")
73-
.short('n')
74-
.help("Number of concurrent upstream git fetch/push operations"),
75-
)
70+
.arg(clap::Arg::new("n").short('n').help(
71+
"DEPRECATED - no effect! Number of concurrent upstream git fetch/push operations",
72+
))
7673
.arg(clap::Arg::new("port").long("port"))
7774
.arg(
7875
clap::Arg::new("cache-duration")
@@ -140,7 +137,6 @@ pub fn parse_args() -> josh::JoshResult<Args> {
140137
.clone();
141138

142139
let poll_user = args.get_one::<String>("poll").map(String::clone);
143-
let concurrent_n = parse_int::<usize>(&args, "n", Some(1))?;
144140
let port = parse_int::<u16>(&args, "port", Some(8000))?;
145141
let cache_duration = parse_int::<u64>(&args, "cache-duration", Some(0))?;
146142
let static_resource_proxy_target = args
@@ -156,7 +152,6 @@ pub fn parse_args() -> josh::JoshResult<Args> {
156152
gc: args.get_flag("gc"),
157153
require_auth: args.get_flag("require-auth"),
158154
no_background: args.get_flag("no-background"),
159-
concurrent_n,
160155
port,
161156
cache_duration,
162157
static_resource_proxy_target,

tests/proxy/shell.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
--no-background
1818

1919
-n <n>
20-
Number of concurrent upstream git fetch/push operations
20+
DEPRECATED - no effect! Number of concurrent upstream git fetch/push operations
2121
--port <port>
2222

2323
-c, --cache-duration <cache-duration>

0 commit comments

Comments
 (0)