cli: trim basic help, drop invented flag, parallelize by default
Surface area, not the machinery, was the problem: 16 flags crowded the bare --help. Re-tag so basic shows only the 10 outcome-changing flags; every other flag still works behind --help=<group>. - cut --bt-metadata-timeout, an invented flag with no real counterpart. Keep its 60s magnet-metadata stall as a fixed internal default (bt.go), not a user knob. - fix the parallelism footgun: a bare `got URL` used min(split,x)=1 connection. When -x is unset, let --split drive per-host connections (capped at 16), so `got URL` gets 5 and `-s16` gets 16. An explicit -x is honored verbatim, including -x1. Locked by TestHTTPConnDefault. - -s is the per-download speed dial now, so it moves to basic; -x (a per-server cap) moves to the http group. -j help says "files at once, not connections within one file".
This commit is contained in:
27
bt/bt.go
27
bt/bt.go
@@ -184,7 +184,6 @@ type Options struct {
|
||||
SeedTime time.Duration // how long to seed (0 with SeedTimeSet means no seeding)
|
||||
SeedRatio float64 // stop seeding at this ratio; checked alongside SeedTime
|
||||
StopTimeout time.Duration // abort if no download progress for this long (0 = off)
|
||||
MetaTimeout time.Duration // abort a magnet that can't fetch metadata in this long (0 = off)
|
||||
SelectFiles map[int]bool // 1-based file indexes to fetch; empty = all
|
||||
CheckIntegrity bool // re-verify data against piece hashes before downloading
|
||||
DryRun bool // fetch metadata only, then stop without downloading (--dry-run)
|
||||
@@ -374,27 +373,27 @@ func (d *Download) choose(t *torrent.Torrent) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// awaitInfo blocks until the torrent metadata arrives. It gives up after
|
||||
// --bt-metadata-timeout (default 60s) so a magnet with no reachable peers — a
|
||||
// dead link, or UDP trackers behind a firewall with no DHT — fails fast instead
|
||||
// of hanging forever. Setting --bt-metadata-timeout=0 disables the timeout and
|
||||
// waits indefinitely.
|
||||
// metadataTimeout bounds the magnet metadata-fetch phase. A magnet with no
|
||||
// reachable peers — a dead link, or UDP trackers behind a firewall with no DHT —
|
||||
// would otherwise hang forever, so awaitInfo gives up after this fixed window.
|
||||
// It is not a user-facing flag: aria2 has no --bt-metadata-timeout, and 60s is a
|
||||
// generous ceiling that a healthy swarm clears in well under a second.
|
||||
const metadataTimeout = 60 * time.Second
|
||||
|
||||
// awaitInfo blocks until the torrent metadata arrives, giving up after
|
||||
// metadataTimeout so a peerless magnet fails fast instead of hanging forever.
|
||||
func (d *Download) awaitInfo(ctx context.Context, t *torrent.Torrent) error {
|
||||
var deadline <-chan time.Time
|
||||
if d.opts.MetaTimeout > 0 {
|
||||
tm := time.NewTimer(d.opts.MetaTimeout)
|
||||
defer tm.Stop()
|
||||
deadline = tm.C
|
||||
}
|
||||
tm := time.NewTimer(metadataTimeout)
|
||||
defer tm.Stop()
|
||||
select {
|
||||
case <-t.GotInfo():
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-deadline:
|
||||
case <-tm.C:
|
||||
// Wrap DeadlineExceeded so the exit-code mapping classifies it as a timeout
|
||||
// (2) via errors.Is, rather than matching on the message text.
|
||||
return fmt.Errorf("timed out fetching metadata after %s: %w", d.opts.MetaTimeout, context.DeadlineExceeded)
|
||||
return fmt.Errorf("timed out fetching metadata after %s: %w", metadataTimeout, context.DeadlineExceeded)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user