Skip to content

Commit

Permalink
metricwriter: compile regular expressions only on first use
Browse files Browse the repository at this point in the history
Compile the regular expressions only on first use rather than implicitly
as part of the `init()` function of the package. This prevents taking a
speed hit on the initialization of the package regardless if this type
is used and moves it to the time when a regular expression is first
used.

Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
  • Loading branch information
jsternberg committed Aug 5, 2024
1 parent e2f6808 commit 2810f20
Showing 1 changed file with 33 additions and 25 deletions.
58 changes: 33 additions & 25 deletions util/progress/metricwriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,31 @@ import (
"golang.org/x/text/language"
)

type rePatterns struct {
LocalSourceType *regexp.Regexp
ImageSourceType *regexp.Regexp
ExecType *regexp.Regexp
ExportImageType *regexp.Regexp
LintMessage *regexp.Regexp
}

var re = sync.OnceValue(func() *rePatterns {
return &rePatterns{
LocalSourceType: regexp.MustCompile(
strings.Join([]string{
`(?P<context>\[internal] load build context)`,
`(?P<dockerfile>load build definition)`,
`(?P<dockerignore>load \.dockerignore)`,
`(?P<namedcontext>\[context .+] load from client)`,
}, "|"),
),
ImageSourceType: regexp.MustCompile(`^\[.*] FROM `),
ExecType: regexp.MustCompile(`^\[.*] RUN `),
ExportImageType: regexp.MustCompile(`^exporting to (image|(?P<format>\w+) image format)$`),
LintMessage: regexp.MustCompile(`^https://docs\.docker\.com/go/dockerfile/rule/([\w|-]+)/`),
}
})

type metricWriter struct {
recorders []metricRecorder
attrs attribute.Set
Expand Down Expand Up @@ -128,22 +153,13 @@ func (mr *localSourceTransferMetricRecorder) Record(ss *client.SolveStatus) {
}
}

var reLocalSourceType = regexp.MustCompile(
strings.Join([]string{
`(?P<context>\[internal] load build context)`,
`(?P<dockerfile>load build definition)`,
`(?P<dockerignore>load \.dockerignore)`,
`(?P<namedcontext>\[context .+] load from client)`,
}, "|"),
)

func detectLocalSourceType(vertexName string) attribute.KeyValue {
match := reLocalSourceType.FindStringSubmatch(vertexName)
match := re().LocalSourceType.FindStringSubmatch(vertexName)
if match == nil {
return attribute.KeyValue{}
}

for i, source := range reLocalSourceType.SubexpNames() {
for i, source := range re().LocalSourceType.SubexpNames() {
if len(source) == 0 {
// Not a subexpression.
continue
Expand Down Expand Up @@ -241,10 +257,8 @@ func (mr *imageSourceMetricRecorder) Record(ss *client.SolveStatus) {
}
}

var reImageSourceType = regexp.MustCompile(`^\[.*] FROM `)

func detectImageSourceType(vertexName string) bool {
return reImageSourceType.MatchString(vertexName)
return re().ImageSourceType.MatchString(vertexName)
}

type (
Expand Down Expand Up @@ -278,10 +292,8 @@ func (mr *execMetricRecorder) Record(ss *client.SolveStatus) {
}
}

var reExecType = regexp.MustCompile(`^\[.*] RUN `)

func detectExecType(vertexName string) bool {
return reExecType.MatchString(vertexName)
return re().ExecType.MatchString(vertexName)
}

type (
Expand Down Expand Up @@ -325,10 +337,8 @@ func (mr *exportImageMetricRecorder) Record(ss *client.SolveStatus) {
}
}

var reExportImageType = regexp.MustCompile(`^exporting to (image|(?P<format>\w+) image format)$`)

func detectExportImageType(vertexName string) string {
m := reExportImageType.FindStringSubmatch(vertexName)
m := re().ExportImageType.FindStringSubmatch(vertexName)
if m == nil {
return ""
}
Expand Down Expand Up @@ -456,7 +466,10 @@ func kebabToCamel(s string) string {
return strings.Join(words, "")
}

var lintRuleNameProperty = attribute.Key("lint.rule.name")

func (mr *lintMetricRecorder) Record(ss *client.SolveStatus) {
reLintMessage := re().LintMessage
for _, warning := range ss.Warnings {
m := reLintMessage.FindSubmatch([]byte(warning.URL))
if len(m) < 2 {
Expand All @@ -472,8 +485,3 @@ func (mr *lintMetricRecorder) Record(ss *client.SolveStatus) {
)
}
}

var (
reLintMessage = regexp.MustCompile(`^https://docs\.docker\.com/go/dockerfile/rule/([\w|-]+)/`)
lintRuleNameProperty = attribute.Key("lint.rule.name")
)

0 comments on commit 2810f20

Please sign in to comment.