Dead, vestigial, and over-built code with no behavior change (except the
bool-vocabulary trim, a deliberate behavior tightening):
- httpdl: drop the vestigial sort+copy in validSegs (work-stealing was
removed in 270812d, so segments always tile [0,total) ascending now);
validate order in place, which also rejects a scrambled sidecar. Inline
the endOff() accessor to s.end.
- cli: shrink the boolean vocabulary to true/false, which is all that's
accepted. The invented yes/no/1/0/on/off spellings are gone, so e.g.
--enable-dht=yes (or yes in got.conf) is now a usage error.
- download: remove the dead, never-called Stat.Done() method.
- progress: drop speed(), a pure alias of humanSize; call humanSize directly.
- main: replace the jobsHolder mutex box with atomic.Pointer[[]job] for the
forced-exit session save; the capability stays, the lock and type go.
- bt: collapse isAddrInUse's X||X (missinggo.IsAddrInUse is that exact
string match); drop the now-unused missinggo import (tidy -> indirect).
- option: note that prealloc and falloc are identical here.
67 lines
2.1 KiB
Go
67 lines
2.1 KiB
Go
// Package download defines the core abstraction of the program: a Download is
|
|
// a thing you can Run and ask for a Stat snapshot. Where a single-threaded
|
|
// Command/event-poll reactor would express this, we use one
|
|
// goroutine per Download blocking on real I/O. Following Rob Pike, the data
|
|
// (Stat) and the interface are kept small; the algorithms fall out of them.
|
|
package download
|
|
|
|
import "context"
|
|
|
|
// Status is the coarse lifecycle state of a download, using the
|
|
// active/waiting/complete/error vocabulary.
|
|
type Status int
|
|
|
|
const (
|
|
Waiting Status = iota
|
|
Active
|
|
Seeding
|
|
Complete
|
|
Errored
|
|
)
|
|
|
|
func (s Status) String() string {
|
|
switch s {
|
|
case Waiting:
|
|
return "waiting"
|
|
case Active:
|
|
return "active"
|
|
case Seeding:
|
|
return "seeding"
|
|
case Complete:
|
|
return "complete"
|
|
case Errored:
|
|
return "error"
|
|
default:
|
|
return "unknown"
|
|
}
|
|
}
|
|
|
|
// Stat is a snapshot of a download's progress. Every field is a plain value so
|
|
// a renderer running in another goroutine can copy it without sharing memory.
|
|
// Completed and Uploaded are cumulative byte counters; the renderer derives
|
|
// speeds from successive snapshots rather than each download tracking its own.
|
|
type Stat struct {
|
|
Name string
|
|
// ID is a process-unique stable identity for this download. Name can
|
|
// collide (two pre-metadata magnets both show their source string), so the
|
|
// renderer keys its per-download speed samples on ID, not Name.
|
|
ID string
|
|
IsBT bool // true for BitTorrent; progress always shows CN and shows SD for torrents
|
|
Status Status
|
|
Total int64 // total bytes, or -1 if not yet known
|
|
Completed int64 // bytes downloaded so far
|
|
Uploaded int64 // bytes uploaded (BitTorrent), 0 otherwise
|
|
Conns int // active connections / peers
|
|
Seeders int // connected seeders (BitTorrent only)
|
|
}
|
|
|
|
// A Download is one logical job: a URL, a torrent, a magnet. Run blocks in its
|
|
// own goroutine until the work finishes, fails, or ctx is cancelled. Stat may
|
|
// be called concurrently at any time and must not block; implementations back
|
|
// it with atomics or a briefly-held lock.
|
|
type Download interface {
|
|
Name() string
|
|
Run(ctx context.Context) error
|
|
Stat() Stat
|
|
}
|