Skip to content

Downloads can hang forever in reqwest send() (no request timeout), freezing all download workers #32

@bugrax

Description

@bugrax

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions