first commit
This commit is contained in:
69
download/download.go
Normal file
69
download/download.go
Normal file
@@ -0,0 +1,69 @@
|
||||
// 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)
|
||||
}
|
||||
|
||||
// Done reports whether the download has reached a terminal state.
|
||||
func (s Stat) Done() bool { return s.Status == Complete || s.Status == Errored }
|
||||
|
||||
// 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
|
||||
}
|
||||
Reference in New Issue
Block a user