Skip to content

Commit 2eca31d

Browse files
authored
incremental improvement in catalogmetadata cache/client performance (#965)
Signed-off-by: Joe Lanford <[email protected]>
1 parent d510ad1 commit 2eca31d

11 files changed

+502
-356
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ test-ext-dev-e2e: $(OPERATOR_SDK) $(KUSTOMIZE) $(KIND) #HELP Run extension creat
135135
ENVTEST_VERSION := $(shell go list -m k8s.io/client-go | cut -d" " -f2 | sed 's/^v0\.\([[:digit:]]\{1,\}\)\.[[:digit:]]\{1,\}$$/1.\1.x/')
136136
UNIT_TEST_DIRS := $(shell go list ./... | grep -v /test/)
137137
test-unit: $(SETUP_ENVTEST) #HELP Run the unit tests
138-
eval $$($(SETUP_ENVTEST) use -p env $(ENVTEST_VERSION) $(SETUP_ENVTEST_BIN_DIR_OVERRIDE)) && go test -count=1 -short $(UNIT_TEST_DIRS) -coverprofile cover.out
138+
eval $$($(SETUP_ENVTEST) use -p env $(ENVTEST_VERSION) $(SETUP_ENVTEST_BIN_DIR_OVERRIDE)) && CGO_ENABLED=1 go test -count=1 -race -short $(UNIT_TEST_DIRS) -coverprofile cover.out
139139

140140
image-registry: ## Setup in-cluster image registry
141141
./test/tools/image-registry.sh $(E2E_REGISTRY_NAMESPACE) $(E2E_REGISTRY_NAME)

internal/catalogmetadata/cache/cache.go

+36-22
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ package cache
33
import (
44
"context"
55
"fmt"
6-
"io"
6+
"io/fs"
77
"net/http"
88
"os"
99
"path/filepath"
1010
"sync"
1111

1212
catalogd "github.com/operator-framework/catalogd/api/core/v1alpha1"
13+
"github.com/operator-framework/operator-registry/alpha/declcfg"
1314

1415
"github.com/operator-framework/operator-controller/internal/catalogmetadata/client"
1516
)
@@ -66,7 +67,7 @@ type filesystemCache struct {
6667
// resources that have been successfully reconciled, unpacked, and are being served.
6768
// These requirements help ensure that we can rely on status conditions to determine
6869
// when to issue a request to update the cached Catalog contents.
69-
func (fsc *filesystemCache) FetchCatalogContents(ctx context.Context, catalog *catalogd.ClusterCatalog) (io.ReadCloser, error) {
70+
func (fsc *filesystemCache) FetchCatalogContents(ctx context.Context, catalog *catalogd.ClusterCatalog) (fs.FS, error) {
7071
if catalog == nil {
7172
return nil, fmt.Errorf("error: provided catalog must be non-nil")
7273
}
@@ -80,25 +81,23 @@ func (fsc *filesystemCache) FetchCatalogContents(ctx context.Context, catalog *c
8081
}
8182

8283
cacheDir := filepath.Join(fsc.cachePath, catalog.Name)
83-
cacheFilePath := filepath.Join(cacheDir, "data.json")
84-
8584
fsc.mutex.RLock()
8685
if data, ok := fsc.cacheDataByCatalogName[catalog.Name]; ok {
8786
if catalog.Status.ResolvedSource.Image.ResolvedRef == data.ResolvedRef {
8887
fsc.mutex.RUnlock()
89-
return os.Open(cacheFilePath)
88+
return os.DirFS(cacheDir), nil
9089
}
9190
}
9291
fsc.mutex.RUnlock()
9392

9493
req, err := http.NewRequestWithContext(ctx, http.MethodGet, catalog.Status.ContentURL, nil)
9594
if err != nil {
96-
return nil, fmt.Errorf("error forming request: %s", err)
95+
return nil, fmt.Errorf("error forming request: %v", err)
9796
}
9897

9998
resp, err := fsc.client.Do(req)
10099
if err != nil {
101-
return nil, fmt.Errorf("error performing request: %s", err)
100+
return nil, fmt.Errorf("error performing request: %v", err)
102101
}
103102
defer resp.Body.Close()
104103

@@ -117,34 +116,49 @@ func (fsc *filesystemCache) FetchCatalogContents(ctx context.Context, catalog *c
117116
// the cached contents
118117
if data, ok := fsc.cacheDataByCatalogName[catalog.Name]; ok {
119118
if data.ResolvedRef == catalog.Status.ResolvedSource.Image.Ref {
120-
return os.Open(cacheFilePath)
119+
return os.DirFS(cacheDir), nil
121120
}
122121
}
123122

124-
if err = os.MkdirAll(cacheDir, os.ModePerm); err != nil {
125-
return nil, fmt.Errorf("error creating cache directory for Catalog %q: %s", catalog.Name, err)
126-
}
127-
128-
file, err := os.Create(cacheFilePath)
123+
tmpDir, err := os.MkdirTemp(fsc.cachePath, fmt.Sprintf(".%s-", catalog.Name))
129124
if err != nil {
130-
return nil, fmt.Errorf("error creating cache file for Catalog %q: %s", catalog.Name, err)
125+
return nil, fmt.Errorf("error creating temporary directory to unpack catalog metadata: %v", err)
131126
}
132127

133-
if _, err := io.Copy(file, resp.Body); err != nil {
134-
return nil, fmt.Errorf("error writing contents to cache file for Catalog %q: %s", catalog.Name, err)
128+
if err := declcfg.WalkMetasReader(resp.Body, func(meta *declcfg.Meta, err error) error {
129+
if err != nil {
130+
return fmt.Errorf("error parsing catalog contents: %v", err)
131+
}
132+
pkgName := meta.Package
133+
if meta.Schema == declcfg.SchemaPackage {
134+
pkgName = meta.Name
135+
}
136+
metaName := meta.Name
137+
if meta.Name == "" {
138+
metaName = meta.Schema
139+
}
140+
metaPath := filepath.Join(tmpDir, pkgName, meta.Schema, metaName+".json")
141+
if err := os.MkdirAll(filepath.Dir(metaPath), os.ModePerm); err != nil {
142+
return fmt.Errorf("error creating directory for catalog metadata: %v", err)
143+
}
144+
if err := os.WriteFile(metaPath, meta.Blob, os.ModePerm); err != nil {
145+
return fmt.Errorf("error writing catalog metadata to file: %v", err)
146+
}
147+
return nil
148+
}); err != nil {
149+
return nil, err
135150
}
136151

137-
if err = file.Sync(); err != nil {
138-
return nil, fmt.Errorf("error syncing contents to cache file for Catalog %q: %s", catalog.Name, err)
152+
if err := os.RemoveAll(cacheDir); err != nil {
153+
return nil, fmt.Errorf("error removing old cache directory: %v", err)
139154
}
140-
141-
if _, err = file.Seek(0, 0); err != nil {
142-
return nil, fmt.Errorf("error resetting offset for cache file reader for Catalog %q: %s", catalog.Name, err)
155+
if err := os.Rename(tmpDir, cacheDir); err != nil {
156+
return nil, fmt.Errorf("error moving temporary directory to cache directory: %v", err)
143157
}
144158

145159
fsc.cacheDataByCatalogName[catalog.Name] = cacheData{
146160
ResolvedRef: catalog.Status.ResolvedSource.Image.ResolvedRef,
147161
}
148162

149-
return file, nil
163+
return os.DirFS(cacheDir), nil
150164
}

0 commit comments

Comments
 (0)