download: free the -j slot once a torrent starts seeding

This commit is contained in:
2026-06-22 01:57:03 +09:00
parent 6e77cde4cc
commit b632f37e3d
4 changed files with 149 additions and 2 deletions

View File

@@ -60,7 +60,24 @@ func (e *Engine) Run(ctx context.Context, downloads []Download) []Result {
results <- Result{Name: d.Name(), Index: i, Err: ctx.Err(), Stat: d.Stat()}
return
}
defer func() { <-slots }()
// Release the slot exactly once — whether the download finishes or, for
// a torrent, first detaches into seed-only. A seeding torrent is no
// longer downloading, so it stops counting against -j and lets a queued
// download start; this goroutine lives on to seed.
var once sync.Once
release := func() { once.Do(func() { <-slots }) }
defer release()
if s, ok := d.(Seeder); ok {
done := make(chan struct{})
defer close(done)
go func() {
select {
case <-s.SeedingStarted():
release()
case <-done:
}
}()
}
err := d.Run(ctx)
results <- Result{Name: d.Name(), Index: i, Err: err, Stat: d.Stat()}