Cache runtime version metadata fallback

This commit is contained in:
2026-10-09 01:46:07 +00:00
parent 50d3573257
commit 42569b4af2
5 changed files with 94 additions and 4 deletions

View File

@@ -18,7 +18,19 @@ func BenchmarkPerformanceVersion(b *testing.B) {
}
}
})
b.Run("FallbackInitialization", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
fallback := newFallbackVersion(debug.ReadBuildInfo)
performanceVersionSink = fallback()
if performanceVersionSink == "" {
b.Fatal("fallback returned an empty version")
}
}
})
b.Run("RealMetadataFallback", func(b *testing.B) {
_ = Version()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {

View File

@@ -2,14 +2,26 @@
// public buildinfo facade.
package runtimeinfo
import "runtime/debug"
import (
"runtime/debug"
"sync"
)
var injectedVersion string
// Version returns the injected version or the running executable's main module
// version, falling back to "dev" when neither provides a release identifier.
func Version() string {
return version(injectedVersion, debug.ReadBuildInfo)
if injectedVersion != "" {
return injectedVersion
}
return fallbackVersion()
}
var fallbackVersion = newFallbackVersion(debug.ReadBuildInfo)
func newFallbackVersion(readBuildInfo func() (*debug.BuildInfo, bool)) func() string {
return sync.OnceValue(func() string { return version("", readBuildInfo) })
}
func version(injected string, readBuildInfo func() (*debug.BuildInfo, bool)) string {

View File

@@ -2,6 +2,8 @@ package runtimeinfo
import (
"runtime/debug"
"sync"
"sync/atomic"
"testing"
)
@@ -55,3 +57,54 @@ func TestVersion(t *testing.T) {
})
}
}
func TestFallbackVersionReadsMetadataOnceConcurrently(t *testing.T) {
var reads atomic.Int32
fallback := newFallbackVersion(func() (*debug.BuildInfo, bool) {
reads.Add(1)
return &debug.BuildInfo{Main: debug.Module{Version: "v4.5.6"}}, true
})
const callers = 32
results := make(chan string, callers)
var workers sync.WaitGroup
workers.Add(callers)
for i := 0; i < callers; i++ {
go func() {
defer workers.Done()
results <- fallback()
}()
}
workers.Wait()
close(results)
for result := range results {
if result != "v4.5.6" {
t.Errorf("fallback() = %q, want stable version", result)
}
}
if got := reads.Load(); got != 1 {
t.Fatalf("metadata reader called %d times, want once", got)
}
}
func TestFallbackVersionCachesUnavailableAndDevelopmentMetadata(t *testing.T) {
for _, test := range []struct {
name string
read func() (*debug.BuildInfo, bool)
}{
{name: "unavailable", read: func() (*debug.BuildInfo, bool) { return nil, false }},
{name: "development", read: func() (*debug.BuildInfo, bool) {
return &debug.BuildInfo{Main: debug.Module{Version: "(devel)"}}, true
}},
} {
t.Run(test.name, func(t *testing.T) {
fallback := newFallbackVersion(test.read)
if got := fallback(); got != "dev" {
t.Fatalf("fallback() = %q, want dev", got)
}
if got := fallback(); got != "dev" {
t.Fatalf("repeated fallback() = %q, want dev", got)
}
})
}
}