fix: move single-flight to stash (#2050)

This commit is contained in:
south-mer
2025-07-08 17:00:59 +09:00
committed by GitHub
parent 33f32fd3af
commit 25b890553a
2 changed files with 83 additions and 79 deletions
+49 -58
View File
@@ -14,7 +14,6 @@ import (
"github.com/gomods/athens/pkg/observ"
"github.com/gomods/athens/pkg/storage"
"github.com/spf13/afero"
"golang.org/x/sync/singleflight"
)
type goGetFetcher struct {
@@ -22,7 +21,6 @@ type goGetFetcher struct {
goBinaryName string
envVars []string
gogetDir string
sfg *singleflight.Group
}
type goModule struct {
@@ -48,7 +46,6 @@ func NewGoGetFetcher(goBinaryName, gogetDir string, envVars []string, fs afero.F
goBinaryName: goBinaryName,
envVars: envVars,
gogetDir: gogetDir,
sfg: &singleflight.Group{},
}, nil
}
@@ -59,63 +56,57 @@ func (g *goGetFetcher) Fetch(ctx context.Context, mod, ver string) (*storage.Ver
ctx, span := observ.StartSpan(ctx, op.String())
defer span.End()
resp, err, _ := g.sfg.Do(mod+"###"+ver, func() (any, error) {
// setup the GOPATH
goPathRoot, err := afero.TempDir(g.fs, g.gogetDir, "athens")
if err != nil {
return nil, errors.E(op, err)
}
sourcePath := filepath.Join(goPathRoot, "src")
modPath := filepath.Join(sourcePath, getRepoDirName(mod, ver))
if err := g.fs.MkdirAll(modPath, os.ModeDir|os.ModePerm); err != nil {
_ = clearFiles(g.fs, goPathRoot)
return nil, errors.E(op, err)
}
m, err := downloadModule(
ctx,
g.goBinaryName,
g.envVars,
goPathRoot,
modPath,
mod,
ver,
)
if err != nil {
_ = clearFiles(g.fs, goPathRoot)
return nil, errors.E(op, err)
}
var storageVer storage.Version
storageVer.Semver = m.Version
info, err := afero.ReadFile(g.fs, m.Info)
if err != nil {
return nil, errors.E(op, err)
}
storageVer.Info = info
gomod, err := afero.ReadFile(g.fs, m.GoMod)
if err != nil {
return nil, errors.E(op, err)
}
storageVer.Mod = gomod
zip, err := g.fs.Open(m.Zip)
if err != nil {
return nil, errors.E(op, err)
}
// note: don't close zip here so that the caller can read directly from disk.
//
// if we close, then the caller will panic, and the alternative to make this work is
// that we read into memory and return an io.ReadCloser that reads out of memory
storageVer.Zip = &zipReadCloser{zip, g.fs, goPathRoot}
return &storageVer, nil
})
// setup the GOPATH
goPathRoot, err := afero.TempDir(g.fs, g.gogetDir, "athens")
if err != nil {
return nil, err
return nil, errors.E(op, err)
}
return resp.(*storage.Version), nil
sourcePath := filepath.Join(goPathRoot, "src")
modPath := filepath.Join(sourcePath, getRepoDirName(mod, ver))
if err := g.fs.MkdirAll(modPath, os.ModeDir|os.ModePerm); err != nil {
_ = clearFiles(g.fs, goPathRoot)
return nil, errors.E(op, err)
}
m, err := downloadModule(
ctx,
g.goBinaryName,
g.envVars,
goPathRoot,
modPath,
mod,
ver,
)
if err != nil {
_ = clearFiles(g.fs, goPathRoot)
return nil, errors.E(op, err)
}
var storageVer storage.Version
storageVer.Semver = m.Version
info, err := afero.ReadFile(g.fs, m.Info)
if err != nil {
return nil, errors.E(op, err)
}
storageVer.Info = info
gomod, err := afero.ReadFile(g.fs, m.GoMod)
if err != nil {
return nil, errors.E(op, err)
}
storageVer.Mod = gomod
zip, err := g.fs.Open(m.Zip)
if err != nil {
return nil, errors.E(op, err)
}
// note: don't close zip here so that the caller can read directly from disk.
//
// if we close, then the caller will panic, and the alternative to make this work is
// that we read into memory and return an io.ReadCloser that reads out of memory
storageVer.Zip = &zipReadCloser{zip, g.fs, goPathRoot}
return &storageVer, nil
}
// given a filesystem, gopath, repository root, module and version, runs 'go mod download -json'