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