reference icon indicating copy to clipboard operation
reference copied to clipboard

use sync.OnceValue for various regular expressions, require go1.21

Open thaJeztah opened this issue 1 year ago • 7 comments

  • [x] depends on https://github.com/distribution/reference/pull/16

use sync.OnceValue for various regular expressions, require go1.21

Using regex.MustCompile consumes a significant amount of memory when importing the package, even if those regular expressions are not used.

This changes compiling the regular expressions to use a sync.OnceValue so that they're only compiled the first time they're used.

There are various regular expressions remaining that are still compiled on import, but these are exported, so changing them to a sync.OnceValue would be a breaking change; we can still decide to do so, but leaving that for a follow-up.

It's worth noting that sync.OnceValue requires go1.21 or up, so raising the minimum version accordingly.

Before / After (on the docker CLI (GODEBUG=inittrace=1 ./build/docker)):

init github.com/distribution/reference @11 ms,   0.63 ms clock, 414456 bytes, 3599 allocs
init github.com/distribution/reference  @9.8 ms, 0.44 ms clock, 236680 bytes, 1398 allocs

thaJeztah avatar Jul 15 '24 11:07 thaJeztah

Codecov Report

Attention: Patch coverage is 94.73684% with 1 line in your changes missing coverage. Please review.

Project coverage is 84.19%. Comparing base (f0f7bf2) to head (aeed5e6). Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
reference.go 80.00% 1 Missing :warning:
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #15      +/-   ##
==========================================
+ Coverage   83.71%   84.19%   +0.48%     
==========================================
  Files           5        5              
  Lines         393      405      +12     
==========================================
+ Hits          329      341      +12     
  Misses         54       54              
  Partials       10       10              

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

codecov[bot] avatar Jul 15 '24 11:07 codecov[bot]

/cc @tonistiigi

thaJeztah avatar Jul 15 '24 12:07 thaJeztah

Yes; regexes being "hungry" on resources is a known issue in general, which is also why Kir made various pull requests some time ago to try to reduce their use (e.g. https://github.com/docker/go-units/pull/40), but this one cam through @tonistiigi who found that docker/buildx forgot to update docker/registry to the latest version, and as a result the distribution/reference package was loaded twice (once from docker/distribution/reference` and once from the new module.

For a long-lived process / daemon, it's probably less problematic, but in the CLI, this resulted in nearly 2MB to be used just by importing those packages; here's from a Slack thread on that;

reference package(s) allocate nearly 2MB of memory inside init()

init github.com/containerd/containerd/reference @68 ms, 0.002 ms clock, 776 bytes, 10 allocs
init github.com/distribution/reference @68 ms, 1.5 ms clock, 414456 bytes, 3599 allocs
init github.com/docker/distribution/reference @70 ms, 2.2 ms clock, 1368728 bytes, 11434 allocs

So this is an attempt at reducing such cases, and making the regexes compiled on first use.

thaJeztah avatar Jul 15 '24 14:07 thaJeztah

@thaJeztah now that https://github.com/distribution/reference/pull/16 has been merged, wanna open this for review?

milosgajdos avatar Aug 05 '24 22:08 milosgajdos

ping @thaJeztah

milosgajdos avatar Nov 05 '24 11:11 milosgajdos

We need to bump Go on this repo 🙈

milosgajdos avatar Apr 11 '25 07:04 milosgajdos

@milosgajdos failure was because an invalid golangci-lint.yaml option (deadline was removed from the schema, and now had to be timeout, but both were deprecated in v2); I opened a PR to refresh CI, but it looks like the repository's config is looking for the Analyze (go) and CodeQL actions to start running, and .. they don't (or they have a different name now, for it to not find them 🫠);

  • https://github.com/distribution/reference/pull/21

thaJeztah avatar Apr 11 '25 10:04 thaJeztah