Describe the bug
fetch() only sets a connect_timeout on the shared client and a per-chunk inactivity timeout around the byte stream. The req.send().await call itself — establishing the connection and waiting for the response headers — has no timeout beyond connect. If put.io accepts the TCP connection but then stalls before sending response headers (which happens under load), send() blocks indefinitely.
Because the download workers (download_workers) call fetch() synchronously and the orchestration workers block on done_rx.recv() waiting for them, a few hung send() calls freeze every download worker, then every orchestration worker, and the process stops pulling entirely while transfers pile up COMPLETED on put.io. A restart clears it temporarily.
Evidence
After a restart with ~100 COMPLETED transfers waiting, exactly download_workers * something downloads log download started and then nothing happens: 0 download succeeded, 0 stalled, 0 retry/attempt failed, and zero .downloading files on disk (the temp file is only created after send() returns). The workers are parked inside send().
Proposed fix
Wrap req.send() in a tokio::time::timeout, so a connection that never returns headers fails (and is retried/resumed by the existing retry loop, or eventually gives up and frees the worker) instead of hanging forever.
Environment
- putioarr current
main / v0.6.6, Docker
- Large library being pulled from put.io (put.io under load)
Describe the bug
fetch()only sets aconnect_timeouton the shared client and a per-chunk inactivity timeout around the byte stream. Thereq.send().awaitcall itself — establishing the connection and waiting for the response headers — has no timeout beyond connect. If put.io accepts the TCP connection but then stalls before sending response headers (which happens under load),send()blocks indefinitely.Because the download workers (
download_workers) callfetch()synchronously and the orchestration workers block ondone_rx.recv()waiting for them, a few hungsend()calls freeze every download worker, then every orchestration worker, and the process stops pulling entirely while transfers pile upCOMPLETEDon put.io. A restart clears it temporarily.Evidence
After a restart with ~100
COMPLETEDtransfers waiting, exactlydownload_workers* something downloads logdownload startedand then nothing happens:0download succeeded,0 stalled,0retry/attempt failed, and zero.downloadingfiles on disk (the temp file is only created aftersend()returns). The workers are parked insidesend().Proposed fix
Wrap
req.send()in atokio::time::timeout, so a connection that never returns headers fails (and is retried/resumed by the existing retry loop, or eventually gives up and frees the worker) instead of hanging forever.Environment
main/ v0.6.6, Docker