]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go/internal/modfetch: cache latest revinfo in Versions func
authorBaokun Lee <bk@golangcn.org>
Sun, 1 May 2022 06:32:02 +0000 (14:32 +0800)
committerGopher Robot <gobot@golang.org>
Tue, 28 Jun 2022 18:33:29 +0000 (18:33 +0000)
The responses have been cached by the web2 package before removed
it in CL 170879. This change add latest revinfo cache in Versions
func.

Fixes #51391

Change-Id: I73597e0a6b4938238e69d85e1cbbaa9007776db3
Reviewed-on: https://go-review.googlesource.com/c/go/+/403335
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
Run-TryBot: Lee Baokun <bk@golangcn.org>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/go/internal/modfetch/proxy.go

index 4d63dd56487d068e298c82a92a10f568fb4a84da..2491b7d1852b7b7bb556ae31e659cce9c4ac8519 100644 (file)
@@ -187,6 +187,10 @@ type proxyRepo struct {
        url         *url.URL
        path        string
        redactedURL string
+
+       listLatestOnce sync.Once
+       listLatest     *RevInfo
+       listLatestErr  error
 }
 
 func newProxyRepo(baseURL, path string) (Repo, error) {
@@ -214,7 +218,7 @@ func newProxyRepo(baseURL, path string) (Repo, error) {
        redactedURL := base.Redacted()
        base.Path = strings.TrimSuffix(base.Path, "/") + "/" + enc
        base.RawPath = strings.TrimSuffix(base.RawPath, "/") + "/" + pathEscape(enc)
-       return &proxyRepo{base, path, redactedURL}, nil
+       return &proxyRepo{base, path, redactedURL, sync.Once{}, nil, nil}, nil
 }
 
 func (p *proxyRepo) ModulePath() string {
@@ -278,32 +282,46 @@ func (p *proxyRepo) getBody(path string) (r io.ReadCloser, err error) {
 func (p *proxyRepo) Versions(prefix string) ([]string, error) {
        data, err := p.getBytes("@v/list")
        if err != nil {
+               p.listLatestOnce.Do(func() {
+                       p.listLatest, p.listLatestErr = nil, p.versionError("", err)
+               })
                return nil, p.versionError("", err)
        }
        var list []string
-       for _, line := range strings.Split(string(data), "\n") {
+       allLine := strings.Split(string(data), "\n")
+       for _, line := range allLine {
                f := strings.Fields(line)
                if len(f) >= 1 && semver.IsValid(f[0]) && strings.HasPrefix(f[0], prefix) && !module.IsPseudoVersion(f[0]) {
                        list = append(list, f[0])
                }
        }
+       p.listLatestOnce.Do(func() {
+               p.listLatest, p.listLatestErr = p.latestFromList(allLine)
+       })
        semver.Sort(list)
        return list, nil
 }
 
 func (p *proxyRepo) latest() (*RevInfo, error) {
-       data, err := p.getBytes("@v/list")
-       if err != nil {
-               return nil, p.versionError("", err)
-       }
+       p.listLatestOnce.Do(func() {
+               data, err := p.getBytes("@v/list")
+               if err != nil {
+                       p.listLatestErr = p.versionError("", err)
+                       return
+               }
+               list := strings.Split(string(data), "\n")
+               p.listLatest, p.listLatestErr = p.latestFromList(list)
+       })
+       return p.listLatest, p.listLatestErr
+}
 
+func (p *proxyRepo) latestFromList(allLine []string) (*RevInfo, error) {
        var (
                bestTime             time.Time
                bestTimeIsFromPseudo bool
                bestVersion          string
        )
-
-       for _, line := range strings.Split(string(data), "\n") {
+       for _, line := range allLine {
                f := strings.Fields(line)
                if len(f) >= 1 && semver.IsValid(f[0]) {
                        // If the proxy includes timestamps, prefer the timestamp it reports.