download: free the -j slot once a torrent starts seeding
This commit is contained in:
14
bt/bt.go
14
bt/bt.go
@@ -203,12 +203,17 @@ type Download struct {
|
||||
// t is published once Run adds the torrent to the client. It is atomic so
|
||||
// Stat stays lock-free, exactly like httpdl.Stat and bt's own name field.
|
||||
t atomic.Pointer[torrent.Torrent]
|
||||
|
||||
// seeding is closed once Run finishes downloading and transitions to
|
||||
// seed-only, so the engine can drop this torrent from the -j concurrency
|
||||
// count. Created in New, closed exactly once in Run.
|
||||
seeding chan struct{}
|
||||
}
|
||||
|
||||
// New builds a torrent download on the shared client. source is a .torrent path
|
||||
// when isFile is true, otherwise a magnet URI.
|
||||
func New(client *torrent.Client, source string, isFile bool, opts Options) *Download {
|
||||
d := &Download{client: client, source: source, isFile: isFile, opts: opts}
|
||||
d := &Download{client: client, source: source, isFile: isFile, opts: opts, seeding: make(chan struct{})}
|
||||
if isFile {
|
||||
d.setName(strings.TrimSuffix(filepath.Base(source), ".torrent"))
|
||||
} else {
|
||||
@@ -233,6 +238,12 @@ func (d *Download) setStatus(s download.Status) {
|
||||
atomic.StoreInt32(&d.status, int32(s))
|
||||
}
|
||||
|
||||
// SeedingStarted is closed when this torrent finishes downloading and switches
|
||||
// to seed-only. The engine watches it to release the -j concurrency slot at that
|
||||
// moment: seeding is not downloading, so a seed-only torrent must not hold a slot
|
||||
// that a queued download could use. Implements download.Seeder.
|
||||
func (d *Download) SeedingStarted() <-chan struct{} { return d.seeding }
|
||||
|
||||
// id is the process-unique identity for this download: the infohash once known,
|
||||
// otherwise the source string (a pre-metadata magnet has no infohash yet, and
|
||||
// two such magnets would otherwise collide on Name).
|
||||
@@ -329,6 +340,7 @@ func (d *Download) Run(ctx context.Context) (err error) {
|
||||
}
|
||||
|
||||
d.setStatus(download.Seeding)
|
||||
close(d.seeding) // free the -j slot: a seed-only torrent no longer downloads
|
||||
d.seed(ctx, t)
|
||||
d.setStatus(download.Complete)
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user