Skip to content

Commit

Permalink
internal: cache build info to reduce lock contention
Browse files Browse the repository at this point in the history
  • Loading branch information
darccio committed Jul 4, 2024
1 parent fcda398 commit c6e0a7a
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 8 deletions.
29 changes: 21 additions & 8 deletions internal/gitmetadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ var (
lock = sync.Mutex{}

gitMetadataTags map[string]string
buildInfo *debug.BuildInfo
)

func updateTags(tags map[string]string, key string, value string) {
Expand Down Expand Up @@ -76,13 +77,25 @@ func getTagsFromDDTags() map[string]string {
}
}

// getTagsFromBinary extracts git metadata from binary metadata
func getTagsFromBinary() map[string]string {
res := make(map[string]string)
info, ok := debug.ReadBuildInfo()
if !ok {
log.Debug("ReadBuildInfo failed, skip source code metadata extracting")
return res
// getTagsFromBinary extracts git metadata from binary metadata.
// It assumes it's running under a locked mutex.
func getTagsFromBinary(readBuildInfo func() (*debug.BuildInfo, bool)) map[string]string {
var (
info *debug.BuildInfo
res = make(map[string]string)
)
if buildInfo == nil {
var ok bool
info, ok = readBuildInfo()
if !ok {
// Initialize buildInfo to avoid multiple calls to debug.ReadBuildInfo.
buildInfo = &debug.BuildInfo{}
log.Debug("ReadBuildInfo failed, skip source code metadata extracting")
return res
}
buildInfo = info
} else {
info = buildInfo
}
goPath := info.Path
var vcs, commitSha string
Expand Down Expand Up @@ -116,7 +129,7 @@ func GetGitMetadataTags() map[string]string {
if BoolEnv(EnvGitMetadataEnabledFlag, true) {
updateAllTags(gitMetadataTags, getTagsFromEnv())
updateAllTags(gitMetadataTags, getTagsFromDDTags())
updateAllTags(gitMetadataTags, getTagsFromBinary())
updateAllTags(gitMetadataTags, getTagsFromBinary(debug.ReadBuildInfo))
}

return gitMetadataTags
Expand Down
81 changes: 81 additions & 0 deletions internal/gitmetadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package internal

import (
"runtime/debug"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -54,3 +55,83 @@ func TestRemoveCredentials(t *testing.T) {
})
}
}

func TestGetTagsFromBinary(t *testing.T) {
testCases := []struct {
name string
in string
expected map[string]string
}{
{
name: "empty build info",
expected: map[string]string{},
},
{
name: "build info with module path",
expected: map[string]string{
TagGoPath: "github.com/DataDog/dd-trace-go",
},
},
{
name: "build info with module path and git repository",
expected: map[string]string{
TagGoPath: "github.com/DataDog/dd-trace-go",
TagCommitSha: "123456",
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
readBuildInfo := func() (*debug.BuildInfo, bool) {
info := &debug.BuildInfo{
Settings: []debug.BuildSetting{
{
Key: "vcs",
Value: "git",
},
},
}
if tc.expected[TagGoPath] != "" {
info.Path = tc.expected[TagGoPath]
}
if tc.expected[TagCommitSha] != "" {
info.Settings = append(info.Settings, debug.BuildSetting{
Key: "vcs.revision",
Value: tc.expected[TagCommitSha],
})
}
return info, true
}
tags := getTagsFromBinary(readBuildInfo)
assert.Subset(t, tags, tc.expected)
buildInfo = nil
})
}
}

func TestGetTagsFromBinaryCache(t *testing.T) {
var called int
readBuildInfo := func() (*debug.BuildInfo, bool) {
called++
info := &debug.BuildInfo{
Settings: []debug.BuildSetting{
{
Key: "vcs",
Value: "git",
},
{
Key: "vcs.revision",
Value: "123456",
},
},
}
return info, true
}
tags := getTagsFromBinary(readBuildInfo)
assert.NotEmpty(t, tags)
for i := 0; i < 10; i++ {
res := getTagsFromBinary(readBuildInfo)
assert.Equal(t, tags, res)
}
assert.Equal(t, 1, called)
}

0 comments on commit c6e0a7a

Please sign in to comment.