Consume a context when sourcing ebuild in parallel

This commit is contained in:
Ettore Di Giacinto
2019-11-03 12:03:26 +01:00
parent f0e56d966b
commit 1ee2551325

View File

@@ -19,11 +19,13 @@ package gentoo
// https://gist.github.com/adnaan/6ca68c7985c6f851def3
import (
"context"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"time"
. "github.com/mudler/luet/pkg/logger"
tree "github.com/mudler/luet/pkg/tree"
@@ -74,17 +76,25 @@ func (gb *GentooBuilder) scanEbuild(path string, t pkg.Tree) error {
return nil
}
func (gb *GentooBuilder) worker(i int, wg *sync.WaitGroup, s <-chan string, t pkg.Tree) {
func (gb *GentooBuilder) worker(ctx context.Context, i int, wg *sync.WaitGroup, s <-chan string, t pkg.Tree) {
defer wg.Done()
for path := range s {
Info("#"+strconv.Itoa(i), "parsing", path)
err := gb.scanEbuild(path, t)
if err != nil {
Error(path, ":", err.Error())
for {
select {
case <-ctx.Done():
Info("Worker is done!")
return
case path, ok := <-s:
if !ok {
// Channel closed
return
}
Info("#"+strconv.Itoa(i), "parsing", path)
err := gb.scanEbuild(path, t)
if err != nil {
Error(path, ":", err.Error())
}
}
}
}
func (gb *GentooBuilder) Generate(dir string) (pkg.Tree, error) {
@@ -96,6 +106,8 @@ func (gb *GentooBuilder) Generate(dir string) (pkg.Tree, error) {
Spinner(27)
defer SpinnerStop()
tree := &GentooTree{DefaultTree: &tree.DefaultTree{Packages: pkg.NewInMemoryDatabase(false)}}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
//tree := &GentooTree{DefaultTree: &tree.DefaultTree{Packages: pkg.NewBoltDatabase(tmpfile.Name())}}
Debug("Concurrency", gb.Concurrency)
@@ -103,7 +115,7 @@ func (gb *GentooBuilder) Generate(dir string) (pkg.Tree, error) {
var wg = new(sync.WaitGroup)
for i := 0; i < gb.Concurrency; i++ {
wg.Add(1)
go gb.worker(i, wg, toScan, tree)
go gb.worker(ctx, i, wg, toScan, tree)
}
// TODO: Handle cleaning after? Cleanup implemented in GetPackageSet().Clean()
@@ -121,9 +133,11 @@ func (gb *GentooBuilder) Generate(dir string) (pkg.Tree, error) {
return nil
})
close(toScan)
Debug("Waiting for goroutines to finish")
close(toScan)
wg.Wait() // FIXME: With BoltDB as backend goroutines timeouts and deadlocks
if err != nil {
return tree, err
}