From d35b0f9b3b4e49020ff6916c074749aa4ec4932e Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Fri, 3 May 2024 09:59:01 -0400 Subject: [PATCH] fix ui race for package count Signed-off-by: Alex Goodman --- internal/sbomsync/builder.go | 22 +++++++++++++---- syft/create_sbom.go | 35 +++++++++------------------- syft/format/spdxjson/encoder_test.go | 4 ++-- 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/internal/sbomsync/builder.go b/internal/sbomsync/builder.go index f7404fcebc9..45549b0d560 100644 --- a/internal/sbomsync/builder.go +++ b/internal/sbomsync/builder.go @@ -36,14 +36,22 @@ type Accessor interface { } type sbomBuilder struct { - sbom *sbom.SBOM - lock *sync.RWMutex + sbom *sbom.SBOM + lock *sync.RWMutex + onWrite []func(*sbom.SBOM) } -func NewBuilder(s *sbom.SBOM) Builder { +func NewBuilder(s *sbom.SBOM, onWrite ...func(*sbom.SBOM)) Builder { return &sbomBuilder{ - sbom: s, - lock: &sync.RWMutex{}, + sbom: s, + lock: &sync.RWMutex{}, + onWrite: onWrite, + } +} + +func (b sbomBuilder) onWriteEvent() { + for _, fn := range b.onWrite { + fn(b.sbom) } } @@ -52,6 +60,7 @@ func (b sbomBuilder) WriteToSBOM(fn func(*sbom.SBOM)) { defer b.lock.Unlock() fn(b.sbom) + b.onWriteEvent() } func (b sbomBuilder) ReadFromSBOM(fn func(*sbom.SBOM)) { @@ -66,6 +75,7 @@ func (b sbomBuilder) AddPackages(p ...pkg.Package) { defer b.lock.Unlock() b.sbom.Artifacts.Packages.Add(p...) + b.onWriteEvent() } func (b sbomBuilder) AddRelationships(relationship ...artifact.Relationship) { @@ -73,6 +83,7 @@ func (b sbomBuilder) AddRelationships(relationship ...artifact.Relationship) { defer b.lock.Unlock() b.sbom.Relationships = append(b.sbom.Relationships, relationship...) + b.onWriteEvent() } func (b sbomBuilder) SetLinuxDistribution(release linux.Release) { @@ -80,4 +91,5 @@ func (b sbomBuilder) SetLinuxDistribution(release linux.Release) { defer b.lock.Unlock() b.sbom.Artifacts.LinuxDistribution = &release + b.onWriteEvent() } diff --git a/syft/create_sbom.go b/syft/create_sbom.go index 91eaf8d0399..3e4010eeadf 100644 --- a/syft/create_sbom.go +++ b/syft/create_sbom.go @@ -4,11 +4,9 @@ import ( "context" "fmt" "sort" - "time" "github.com/dustin/go-humanize" "github.com/scylladb/go-set/strset" - "github.com/wagoodman/go-progress" "github.com/anchore/syft/internal/bus" "github.com/anchore/syft/internal/sbomsync" @@ -63,9 +61,9 @@ func CreateSBOM(ctx context.Context, src source.Source, cfg *CreateSBOMConfig) ( } catalogingProgress := monitorCatalogingTask(src.ID(), taskGroups) - packageCatalogingProgress := monitorPackageCatalogingTask(s.Artifacts.Packages) + packageCatalogingProgress := monitorPackageCatalogingTask() - builder := sbomsync.NewBuilder(&s) + builder := sbomsync.NewBuilder(&s, monitorPackageCount(packageCatalogingProgress)) for i := range taskGroups { err := task.NewTaskExecutor(taskGroups[i], cfg.Parallelism).Execute(ctx, resolver, builder, catalogingProgress) if err != nil { @@ -80,7 +78,14 @@ func CreateSBOM(ctx context.Context, src source.Source, cfg *CreateSBOMConfig) ( return &s, nil } -func monitorPackageCatalogingTask(pkgs *pkg.Collection) *monitor.CatalogerTaskProgress { +func monitorPackageCount(prog *monitor.CatalogerTaskProgress) func(s *sbom.SBOM) { + return func(s *sbom.SBOM) { + count := humanize.Comma(int64(s.Artifacts.Packages.PackageCount())) + prog.AtomicStage.Set(fmt.Sprintf("%s packages", count)) + } +} + +func monitorPackageCatalogingTask() *monitor.CatalogerTaskProgress { info := monitor.GenericTask{ Title: monitor.Title{ Default: "Packages", @@ -90,25 +95,7 @@ func monitorPackageCatalogingTask(pkgs *pkg.Collection) *monitor.CatalogerTaskPr ParentID: monitor.TopLevelCatalogingTaskID, } - prog := bus.StartCatalogerTask(info, -1, "") - - go func() { - ticker := time.NewTicker(200 * time.Millisecond) - defer ticker.Stop() - - for { - <-ticker.C - - count := humanize.Comma(int64(pkgs.PackageCount())) - prog.AtomicStage.Set(fmt.Sprintf("%s packages", count)) - - if progress.IsCompleted(prog) { - break - } - } - }() - - return prog + return bus.StartCatalogerTask(info, -1, "") } func monitorCatalogingTask(srcID artifact.ID, tasks [][]task.Task) *monitor.CatalogerTaskProgress { diff --git a/syft/format/spdxjson/encoder_test.go b/syft/format/spdxjson/encoder_test.go index 83999b53f85..6698be490f0 100644 --- a/syft/format/spdxjson/encoder_test.go +++ b/syft/format/spdxjson/encoder_test.go @@ -3,14 +3,14 @@ package spdxjson import ( "bytes" "flag" - "github.com/anchore/syft/syft/artifact" - "github.com/anchore/syft/syft/file" "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/anchore/syft/syft/artifact" + "github.com/anchore/syft/syft/file" "github.com/anchore/syft/syft/format/internal/spdxutil" "github.com/anchore/syft/syft/format/internal/testutil" "github.com/anchore/syft/syft/pkg"