dockerversion: DockerUserAgent(): use sync.Once to construct User-Agent
The User-Agent includes the kernel version, which involves making a syscall (and parsing the results) on Linux, and reading (plus parsing) the registry on Windows. These operations are relatively costly, and we should not perform those on every request that uses the User-Agent. This patch adds a sync.Once so that we only perform these actions once for the lifetime of the daemon's process. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
1855a55d8c
commit
66dfc0169f
1 changed files with 36 additions and 15 deletions
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/docker/pkg/parsers/kernel"
|
||||
"github.com/docker/docker/pkg/useragent"
|
||||
|
@ -17,23 +18,43 @@ type UAStringKey struct{}
|
|||
//
|
||||
// [docker client's UA] UpstreamClient([upstream client's UA])
|
||||
func DockerUserAgent(ctx context.Context) string {
|
||||
httpVersion := make([]useragent.VersionInfo, 0, 6)
|
||||
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "docker", Version: Version})
|
||||
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "go", Version: runtime.Version()})
|
||||
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "git-commit", Version: GitCommit})
|
||||
if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
|
||||
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "kernel", Version: kernelVersion.String()})
|
||||
daemonUA := getDaemonUserAgent()
|
||||
if upstreamUA := getUserAgentFromContext(ctx); len(upstreamUA) > 0 {
|
||||
return insertUpstreamUserAgent(upstreamUA, daemonUA)
|
||||
}
|
||||
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "os", Version: runtime.GOOS})
|
||||
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "arch", Version: runtime.GOARCH})
|
||||
return daemonUA
|
||||
}
|
||||
|
||||
dockerUA := useragent.AppendVersions("", httpVersion...)
|
||||
upstreamUA := getUserAgentFromContext(ctx)
|
||||
if len(upstreamUA) > 0 {
|
||||
ret := insertUpstreamUserAgent(upstreamUA, dockerUA)
|
||||
return ret
|
||||
}
|
||||
return dockerUA
|
||||
var (
|
||||
daemonUAOnce sync.Once
|
||||
daemonUA string
|
||||
)
|
||||
|
||||
// getUserAgentFromContext returns the user-agent to use for requests made by
|
||||
// the daemon.
|
||||
//
|
||||
// It includes;
|
||||
//
|
||||
// - the docker version
|
||||
// - go version
|
||||
// - git-commit
|
||||
// - kernel version
|
||||
// - os
|
||||
// - architecture
|
||||
func getDaemonUserAgent() string {
|
||||
daemonUAOnce.Do(func() {
|
||||
httpVersion := make([]useragent.VersionInfo, 0, 6)
|
||||
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "docker", Version: Version})
|
||||
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "go", Version: runtime.Version()})
|
||||
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "git-commit", Version: GitCommit})
|
||||
if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
|
||||
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "kernel", Version: kernelVersion.String()})
|
||||
}
|
||||
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "os", Version: runtime.GOOS})
|
||||
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "arch", Version: runtime.GOARCH})
|
||||
daemonUA = useragent.AppendVersions("", httpVersion...)
|
||||
})
|
||||
return daemonUA
|
||||
}
|
||||
|
||||
// getUserAgentFromContext returns the previously saved user-agent context stored in ctx, if one exists
|
||||
|
|
Loading…
Reference in a new issue