From aa1c40a1487d32a92049c1824b833f052e3ee5cd Mon Sep 17 00:00:00 2001 From: itexpert228 <67105314+fdaser1337@users.noreply.github.com> Date: Sun, 15 Mar 2026 17:24:01 +0300 Subject: [PATCH] =?UTF-8?q?zaebalsa=D0=B0=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/optimized_build.go | 2 +- pkg/cache/package_index.go | 3 +++ pkg/loader/package_loader.go | 4 ++-- pkg/resolver/global_resolver.go | 14 +++++++++----- test/test_singleton_fix.go | 14 +++++++------- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/cmd/optimized_build.go b/cmd/optimized_build.go index 0be3e51..ce01590 100644 --- a/cmd/optimized_build.go +++ b/cmd/optimized_build.go @@ -100,7 +100,7 @@ func (s *OptimizedAutoBuildSession) initialize() error { fmt.Printf("šŸš€ Initializing fast dependency resolver...\n") // Initialize global resolver (singleton) - r, err := resolver.GetGlobalResolver(s.cacheDir, "https://deb.debian.org/debian", "stable", "main") + r, err := resolver.GetResolver(s.cacheDir, "https://deb.debian.org/debian", "stable", "main") if err != nil { fmt.Printf("āš ļø Failed to initialize global resolver: %v (will use fallback)\n", err) // Continue with fallback resolver diff --git a/pkg/cache/package_index.go b/pkg/cache/package_index.go index a24cf78..de0693a 100644 --- a/pkg/cache/package_index.go +++ b/pkg/cache/package_index.go @@ -111,6 +111,9 @@ func (idx *PackageIndex) AddPackage(entry *PackageEntry) { defer idx.mu.Unlock() idx.packages[entry.Package] = entry + // Mark index as updated so IsExpired() works correctly and + // we don't re-parse Sources.xz on every program run. + idx.lastUpdate = time.Now() // Index binaries for fast lookup for _, binary := range entry.Binaries { diff --git a/pkg/loader/package_loader.go b/pkg/loader/package_loader.go index ace29b4..9db99fb 100644 --- a/pkg/loader/package_loader.go +++ b/pkg/loader/package_loader.go @@ -52,7 +52,7 @@ func (l *PackageLoader) LoadSources(mirror, suite, component string) error { fmt.Printf("āœ… Using fresh cache: %d packages, %d binaries\n", pkgCount, binCount) // Load into global resolver (singleton) - if _, err := resolver.GetGlobalResolver(l.cacheDir, mirror, suite, component); err != nil { + if _, err := resolver.GetResolver(l.cacheDir, mirror, suite, component); err != nil { return fmt.Errorf("failed to load global resolver: %w", err) } @@ -76,7 +76,7 @@ func (l *PackageLoader) LoadSources(mirror, suite, component string) error { fmt.Printf("āœ… Loaded %d packages, %d binaries\n", pkgCount, binCount) // Load into global resolver (singleton) - if _, err := resolver.GetGlobalResolver(l.cacheDir, mirror, suite, component); err != nil { + if _, err := resolver.GetResolver(l.cacheDir, mirror, suite, component); err != nil { return fmt.Errorf("failed to load global resolver: %w", err) } diff --git a/pkg/resolver/global_resolver.go b/pkg/resolver/global_resolver.go index 772ac4a..a23102c 100644 --- a/pkg/resolver/global_resolver.go +++ b/pkg/resolver/global_resolver.go @@ -12,12 +12,10 @@ var ( resolverErr error ) -// GetGlobalResolver returns a singleton FastResolver instance. -// Sources.xz will only be parsed once per process. -func GetGlobalResolver(cacheDir, mirror, suite, component string) (*FastResolver, error) { - +// GetResolver returns a process-wide singleton FastResolver instance. +// Package index loading (and thus Sources.xz parsing) will happen at most once per process. +func GetResolver(cacheDir, mirror, suite, component string) (*FastResolver, error) { resolverOnce.Do(func() { - log.Println("[resolver] Initializing global resolver (loading package index)") r := NewFastResolver(cacheDir) @@ -42,3 +40,9 @@ func GetGlobalResolver(cacheDir, mirror, suite, component string) (*FastResolver return globalResolver, nil } + +// GetGlobalResolver is kept for backward compatibility. +// New code should use GetResolver instead. +func GetGlobalResolver(cacheDir, mirror, suite, component string) (*FastResolver, error) { + return GetResolver(cacheDir, mirror, suite, component) +} diff --git a/test/test_singleton_fix.go b/test/test_singleton_fix.go index 74055e9..e6d7056 100644 --- a/test/test_singleton_fix.go +++ b/test/test_singleton_fix.go @@ -20,14 +20,14 @@ func main() { // Remove any existing cache os.RemoveAll(cacheDir) - // Test 1: Multiple GetGlobalResolver calls should only parse once - fmt.Printf("\nšŸ“¦ Test 1: Multiple GetGlobalResolver calls...\n") + // Test 1: Multiple GetResolver calls should only parse once + fmt.Printf("\nšŸ“¦ Test 1: Multiple GetResolver calls...\n") start := time.Now() - // First call - should parse Sources.xz + // First call - should parse Sources.xz or load JSON cache fmt.Printf("Call 1: ") - r1, err := resolver.GetGlobalResolver(cacheDir, mirror, suite, component) + r1, err := resolver.GetResolver(cacheDir, mirror, suite, component) if err != nil { fmt.Printf("āŒ Error: %v\n", err) return @@ -38,7 +38,7 @@ func main() { // Second call - should be instant start = time.Now() fmt.Printf("Call 2: ") - r2, err := resolver.GetGlobalResolver(cacheDir, mirror, suite, component) + r2, err := resolver.GetResolver(cacheDir, mirror, suite, component) if err != nil { fmt.Printf("āŒ Error: %v\n", err) return @@ -49,7 +49,7 @@ func main() { // Third call - should also be instant start = time.Now() fmt.Printf("Call 3: ") - r3, err := resolver.GetGlobalResolver(cacheDir, mirror, suite, component) + r3, err := resolver.GetResolver(cacheDir, mirror, suite, component) if err != nil { fmt.Printf("āŒ Error: %v\n", err) return @@ -116,6 +116,6 @@ func main() { fmt.Printf("\nšŸ“‹ Expected behavior:\n") fmt.Printf("• LoadIndex() should execute only once inside sync.Once\n") - fmt.Printf("• Subsequent GetGlobalResolver() calls should be <1ms\n") + fmt.Printf("• Subsequent GetResolver() calls should be <1ms\n") fmt.Printf("• Dependency resolutions should not trigger re-parsing\n") }