From 40224e0202294ab810d604d91d99da3e5ae2cff8 Mon Sep 17 00:00:00 2001 From: Aman Sharma Date: Tue, 1 Sep 2026 19:07:41 +0200 Subject: [PATCH] perf: check manifests concurrently in scan.Dir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each manifest's Check is a separate network round-trip to its resolver, so run them in their own goroutine instead of sequentially — a project with several manifest kinds would otherwise serialize their resolver timeouts (10s each) into a slow SessionStart hook. --- pkg/scan/scan.go | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/pkg/scan/scan.go b/pkg/scan/scan.go index 6cbeb3c..677bcf4 100644 --- a/pkg/scan/scan.go +++ b/pkg/scan/scan.go @@ -12,6 +12,7 @@ import ( "os" "path/filepath" "sort" + "sync" "github.com/chains-project/yul/pkg/util/manifestchecker" "github.com/chains-project/yul/pkg/util/mismatch" @@ -124,16 +125,29 @@ func Dir(root string, checkers []manifestchecker.ManifestChecker) ([]Finding, er return nil, err } - var findings []Finding + var ( + wg sync.WaitGroup + mu sync.Mutex + findings []Finding + ) + // Each manifest is checked in its own goroutine. + // Each goroutine bundles all the mismatches so that it can be queried later. for _, m := range manifests { - mismatches, err := m.checker.Check("", string(m.content)) - if err != nil { - continue // resolver/parse error on this file: fail open, keep scanning - } - for _, mm := range mismatches { - findings = append(findings, Finding{File: m.rel, Mismatch: mm}) - } + wg.Add(1) + go func(m manifest) { + defer wg.Done() + mismatches, err := m.checker.Check("", string(m.content)) + if err != nil { + return // resolver/parse error on this file: fail open, keep scanning + } + mu.Lock() + defer mu.Unlock() + for _, mm := range mismatches { + findings = append(findings, Finding{File: m.rel, Mismatch: mm}) + } + }(m) } + wg.Wait() sort.Slice(findings, func(i, j int) bool { if findings[i].File != findings[j].File {