Skip to content

Commit 56d184a

Browse files
authored
catalog cache: retry cache population when cache contains an error (#1489)
Signed-off-by: Joe Lanford <[email protected]>
1 parent 7ffb2ea commit 56d184a

File tree

5 files changed

+16
-25
lines changed

5 files changed

+16
-25
lines changed

internal/catalogmetadata/cache/cache.go

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,6 @@ func (fsc *filesystemCache) Put(catalogName, resolvedRef string, source io.Reade
6060
fsc.mutex.Lock()
6161
defer fsc.mutex.Unlock()
6262

63-
// make sure we only write if this info hasn't been updated
64-
// by another thread. The check here, if multiple threads are
65-
// updating this, has no way to tell if the current ref is the
66-
// newest possible ref. If another thread has already updated
67-
// this to be the same value, skip the write logic and return
68-
// the cached contents.
69-
if cache, err := fsc.get(catalogName, resolvedRef); err == nil && cache != nil {
70-
// We only return here if the was no error during
71-
// the previous (likely concurrent) cache population attempt.
72-
// If there was an error - we want to try and populate the cache again.
73-
return cache, nil
74-
}
75-
7663
var cacheFS fs.FS
7764
if errToCache == nil {
7865
cacheFS, errToCache = fsc.writeFS(catalogName, source)

internal/catalogmetadata/cache/cache_test.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,10 @@ func TestFilesystemCachePutAndGet(t *testing.T) {
9696
assert.NoError(t, equalFilesystems(actualFSPut, actualFSGet))
9797

9898
t.Log("Put v1 error into cache")
99-
actualFSPut, err = c.Put(catalogName, resolvedRef1, nil, errors.New("fake put error"))
100-
// Errors do not override previously successfully populated cache
101-
require.NoError(t, err)
102-
require.NotNil(t, actualFSPut)
103-
assert.NoError(t, equalFilesystems(defaultFS(), actualFSPut))
104-
assert.NoError(t, equalFilesystems(actualFSPut, actualFSGet))
99+
actualFSPut, err = c.Put(catalogName, resolvedRef1, nil, errors.New("fake v1 put error"))
100+
// Errors for an existing resolvedRef should override previously successfully populated cache
101+
assert.Equal(t, err, errors.New("fake v1 put error"))
102+
assert.Nil(t, actualFSPut)
105103

106104
t.Log("Put v2 error into cache")
107105
actualFSPut, err = c.Put(catalogName, resolvedRef2, nil, errors.New("fake v2 put error"))

internal/controllers/clustercatalog_controller.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
apierrors "k8s.io/apimachinery/pkg/api/errors"
2525
ctrl "sigs.k8s.io/controller-runtime"
2626
"sigs.k8s.io/controller-runtime/pkg/client"
27+
"sigs.k8s.io/controller-runtime/pkg/log"
2728

2829
catalogd "github.com/operator-framework/catalogd/api/v1"
2930
)
@@ -47,6 +48,12 @@ type ClusterCatalogReconciler struct {
4748
//+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clustercatalogs,verbs=get;list;watch
4849

4950
func (r *ClusterCatalogReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
51+
l := log.FromContext(ctx).WithName("cluster-catalog")
52+
ctx = log.IntoContext(ctx, l)
53+
54+
l.Info("reconcile starting")
55+
defer l.Info("reconcile ending")
56+
5057
existingCatalog := &catalogd.ClusterCatalog{}
5158
err := r.Client.Get(ctx, req.NamespacedName, existingCatalog)
5259
if apierrors.IsNotFound(err) {
@@ -70,9 +77,8 @@ func (r *ClusterCatalogReconciler) Reconcile(ctx context.Context, req ctrl.Reque
7077

7178
catalogFsys, err := r.CatalogCache.Get(existingCatalog.Name, existingCatalog.Status.ResolvedSource.Image.Ref)
7279
if err != nil {
73-
return ctrl.Result{}, fmt.Errorf("error retrieving cache for catalog %q: %v", existingCatalog.Name, err)
74-
}
75-
if catalogFsys != nil {
80+
l.Info("retrying cache population: found previous error from catalog cache", "cacheErr", err)
81+
} else if catalogFsys != nil {
7682
// Cache already exists so we do not need to populate it
7783
return ctrl.Result{}, nil
7884
}

internal/controllers/clustercatalog_controller_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@ func TestClusterCatalogReconcilerFinalizers(t *testing.T) {
134134
return nil, errors.New("fake error from cache get function")
135135
},
136136
},
137-
wantGetCacheCalled: true,
138-
wantErr: "error retrieving cache for catalog",
137+
wantGetCacheCalled: true,
138+
wantPopulateCacheCalled: true,
139139
},
140140
{
141141
name: "catalog does not exist",

internal/controllers/clusterextension_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ type InstalledBundleGetter interface {
9999
// The operator controller needs to watch all the bundle objects and reconcile accordingly. Though not ideal, but these permissions are required.
100100
// This has been taken from rukpak, and an issue was created before to discuss it: https://github.com/operator-framework/rukpak/issues/800.
101101
func (r *ClusterExtensionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
102-
l := log.FromContext(ctx).WithName("operator-controller")
102+
l := log.FromContext(ctx).WithName("cluster-extension")
103103
ctx = log.IntoContext(ctx, l)
104104

105105
l.Info("reconcile starting")

0 commit comments

Comments
 (0)