fix(lib): let an unanswered upload offer expire
An upload offer counted against the slot cap until the peer accepted it, and a peer that never answered, having gone away or hung, held that slot for the life of the process; with two slots by default, two such peers shut uploads down until a restart. An offer nobody answers within thirty seconds is now dropped, recorded as a failed upload so the operator sees why, and the slot goes to the next in line.
This commit is contained in:
@@ -23,6 +23,7 @@ impl Client {
|
||||
if last_sweep.elapsed() >= CONNECT_SWEEP_INTERVAL {
|
||||
last_sweep = Instant::now();
|
||||
Self::sweep_expired_connects(&client_context);
|
||||
Self::sweep_stale_offers(&client_context);
|
||||
}
|
||||
let operation = match next {
|
||||
Ok(operation) => operation,
|
||||
@@ -718,9 +719,10 @@ impl Client {
|
||||
// address (from the code-9 GetPeerAddress) and
|
||||
// stream the file, or queue until it resolves.
|
||||
let (job_addr, downloader) = match client_context
|
||||
.read_safe()
|
||||
.write_safe()
|
||||
{
|
||||
Ok(ctx) => {
|
||||
Ok(mut ctx) => {
|
||||
ctx.mark_offer_answered(token);
|
||||
let Some(job) = ctx.uploads.get(&token) else {
|
||||
continue;
|
||||
};
|
||||
@@ -875,6 +877,15 @@ impl Client {
|
||||
}
|
||||
}
|
||||
|
||||
fn sweep_stale_offers(client_context: &Arc<RwLock<ClientContext>>) {
|
||||
let freed = client_context
|
||||
.write_safe()
|
||||
.is_ok_and(|mut ctx| ctx.expire_stale_offers(Instant::now()));
|
||||
if freed {
|
||||
Self::pump_upload_queue(client_context);
|
||||
}
|
||||
}
|
||||
|
||||
fn sweep_expired_connects(client_context: &Arc<RwLock<ClientContext>>) {
|
||||
let expired = match client_context.write_safe() {
|
||||
Ok(mut ctx) => ctx.take_expired_connects(Instant::now()),
|
||||
|
||||
Reference in New Issue
Block a user