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

@@ -48,7 +48,7 @@ reports these implemented packages:
| `internal/preparation` | Coordination for expected-commit tag checkout and Go module dependency preparation. | | `internal/preparation` | Coordination for expected-commit tag checkout and Go module dependency preparation. |
| `internal/validation` | Shared Go validation with optional race, full-vet, and static package-compilation target selections, formatting, workspace-file and filesystem-replacement checks, per-blob size limits, and selected Markdown destination and fragment checking; `internal/candidate` retains capture, callback sequencing, and local-state rechecks. | | `internal/validation` | Shared Go validation with optional race, full-vet, and static package-compilation target selections, formatting, workspace-file and filesystem-replacement checks, per-blob size limits, and selected Markdown destination and fragment checking; `internal/candidate` retains capture, callback sequencing, and local-state rechecks. |
| `internal/publish` | Publication guards, one validation run, annotated tag creation, push, and recovery state. | | `internal/publish` | Publication guards, one validation run, annotated tag creation, push, and recovery state. |
| `internal/runtimeinfo` | Private version lookup used by the runtime facade. | | `internal/runtimeinfo` | Injected version selection and cached fallback metadata lookup for the runtime facade. |
| `internal/versioncontract` | Shared stable-version rules and linker-symbol identity. | | `internal/versioncontract` | Shared stable-version rules and linker-symbol identity. |
The `buildinfo` facade depends only on its small runtime implementation. The The `buildinfo` facade depends only on its small runtime implementation. The

View File

@@ -1,6 +1,6 @@
# Computational Efficiency Implementation Plan # Computational Efficiency Implementation Plan
**Status:** Stages 1–9 complete; Stages 10–11 pending. **Status:** Stages 1–10 complete; Stage 11 pending.
## Purpose And Baseline ## Purpose And Baseline
@@ -539,6 +539,19 @@ Run facade/dependency checks. Re-run version benchmarks after initializing the
cache and report initialization separately from repeated access. The runtime cache and report initialization separately from repeated access. The runtime
facade and its dependency boundary retain their existing public shape. facade and its dependency boundary retain their existing public shape.
**Completion:** Complete. `Version` returns the linker-injected value before
touching fallback state, and a private factory wraps the existing pure
selection helper with `sync.OnceValue`. A concurrent counting-reader test
confirms one metadata read and stable results; isolated unavailable and
development cases continue to resolve to `dev`. Runtime, buildinfo, facade
dependency, consumer executable, and focused race tests passed. Three version
benchmark repetitions measured injected selection at 0.75–1.03 ns with no
allocations, fallback initialization at 1.53–1.74 µs with 1,264 B/9 allocations,
and warmed production fallback access at 4.54–4.91 ns with no allocations.
The original uncached metadata call measured 1.438–1.474 µs and 1,184 B/7
allocations per access. The internal package inventory now records the cached
fallback behavior.
## Stage 11: Verify The Complete Implementation And Record Results ## Stage 11: Verify The Complete Implementation And Record Results
**Owners:** Affected tests and canonical internal documentation; roadmap status. **Owners:** Affected tests and canonical internal documentation; roadmap status.

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) { b.Run("RealMetadataFallback", func(b *testing.B) {
_ = Version()
b.ReportAllocs() b.ReportAllocs()
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {

View File

@@ -2,14 +2,26 @@
// public buildinfo facade. // public buildinfo facade.
package runtimeinfo package runtimeinfo
import "runtime/debug" import (
"runtime/debug"
"sync"
)
var injectedVersion string var injectedVersion string
// Version returns the injected version or the running executable's main module // Version returns the injected version or the running executable's main module
// version, falling back to "dev" when neither provides a release identifier. // version, falling back to "dev" when neither provides a release identifier.
func Version() string { 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 { func version(injected string, readBuildInfo func() (*debug.BuildInfo, bool)) string {

View File

@@ -2,6 +2,8 @@ package runtimeinfo
import ( import (
"runtime/debug" "runtime/debug"
"sync"
"sync/atomic"
"testing" "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)
}
})
}
}