perf(manager.go): optimize load chart repositories with concurrent processing

Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
pull/13118/head
Suleiman Dibirov 1 year ago
parent 15f76cf83c
commit 6764d678a5

@ -31,6 +31,7 @@ import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/sync/errgroup"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
"helm.sh/helm/v3/internal/resolver" "helm.sh/helm/v3/internal/resolver"
@ -241,6 +242,7 @@ func (m *Manager) resolve(req []*chart.Dependency, repoNames map[string]string)
// a conflict. // a conflict.
func (m *Manager) downloadAll(deps []*chart.Dependency) error { func (m *Manager) downloadAll(deps []*chart.Dependency) error {
repos, err := m.loadChartRepositories() repos, err := m.loadChartRepositories()
if err != nil { if err != nil {
return err return err
} }
@ -660,7 +662,6 @@ func (m *Manager) UpdateRepositories() error {
} }
func (m *Manager) parallelRepoUpdate(repos []*repo.Entry) error { func (m *Manager) parallelRepoUpdate(repos []*repo.Entry) error {
var wg sync.WaitGroup var wg sync.WaitGroup
for _, c := range repos { for _, c := range repos {
r, err := repo.NewChartRepository(c, m.Getters) r, err := repo.NewChartRepository(c, m.Getters)
@ -670,6 +671,8 @@ func (m *Manager) parallelRepoUpdate(repos []*repo.Entry) error {
r.CachePath = m.RepositoryCache r.CachePath = m.RepositoryCache
wg.Add(1) wg.Add(1)
go func(r *repo.ChartRepository) { go func(r *repo.ChartRepository) {
defer wg.Done()
if _, err := r.DownloadIndexFile(); err != nil { if _, err := r.DownloadIndexFile(); err != nil {
// For those dependencies that are not known to helm and using a // For those dependencies that are not known to helm and using a
// generated key name we display the repo url. // generated key name we display the repo url.
@ -687,7 +690,6 @@ func (m *Manager) parallelRepoUpdate(repos []*repo.Entry) error {
fmt.Fprintf(m.Out, "...Successfully got an update from the %q chart repository\n", r.Config.Name) fmt.Fprintf(m.Out, "...Successfully got an update from the %q chart repository\n", r.Config.Name)
} }
} }
wg.Done()
}(r) }(r)
} }
wg.Wait() wg.Wait()
@ -823,21 +825,40 @@ func (m *Manager) loadChartRepositories() (map[string]*repo.ChartRepository, err
return indices, errors.Wrapf(err, "failed to load %s", m.RepositoryConfig) return indices, errors.Wrapf(err, "failed to load %s", m.RepositoryConfig)
} }
var (
g errgroup.Group
mu sync.Mutex
)
for _, re := range rf.Repositories { for _, re := range rf.Repositories {
lname := re.Name re := re
idxFile := filepath.Join(m.RepositoryCache, helmpath.CacheIndexFile(lname))
index, err := repo.LoadIndexFile(idxFile)
if err != nil {
return indices, err
}
// TODO: use constructor g.Go(func() error {
cr := &repo.ChartRepository{ lname := re.Name
Config: re, idxFile := filepath.Join(m.RepositoryCache, helmpath.CacheIndexFile(lname))
IndexFile: index, index, err := repo.LoadIndexFile(idxFile)
} if err != nil {
indices[lname] = cr return err
}
// TODO: use constructor
cr := &repo.ChartRepository{
Config: re,
IndexFile: index,
}
mu.Lock()
indices[lname] = cr
mu.Unlock()
return nil
})
} }
// Wait for all repositories to be loaded
if err := g.Wait(); err != nil {
return indices, err
}
return indices, nil return indices, nil
} }

Loading…
Cancel
Save