Skip to content

Commit d150428

Browse files
committed
Use ttlcache to expire cached client
1 parent 0faaa5e commit d150428

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

pkg/cloud/client.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,19 @@ package cloud
1818

1919
import (
2020
"bytes"
21+
"fmt"
2122
"io"
2223
"os"
2324
"sync"
25+
"time"
2426

2527
corev1 "k8s.io/api/core/v1"
28+
ctrl "sigs.k8s.io/controller-runtime"
2629

2730
"gopkg.in/yaml.v3"
2831
"sigs.k8s.io/cluster-api-provider-cloudstack/pkg/metrics"
2932

33+
"github.com/ReneKroon/ttlcache"
3034
"github.com/apache/cloudstack-go/v2/cloudstack"
3135
"github.com/pkg/errors"
3236
)
@@ -67,8 +71,11 @@ type SecretConfig struct {
6771
StringData Config `yaml:"stringData"`
6872
}
6973

70-
var clientCache = map[Config]*client{}
74+
var clientCache *ttlcache.Cache
7175
var cacheMutex sync.Mutex
76+
var log = ctrl.Log.WithName("Client")
77+
78+
const cacheExpiration = time.Duration(1 * time.Minute)
7279

7380
// UnmarshalAllSecretConfigs parses a yaml document for each secret.
7481
func UnmarshalAllSecretConfigs(in []byte, out *[]SecretConfig) error {
@@ -141,8 +148,17 @@ func NewClientFromConf(conf Config) (Client, error) {
141148
cacheMutex.Lock()
142149
defer cacheMutex.Unlock()
143150

144-
if client, exists := clientCache[conf]; exists {
145-
return client, nil
151+
if clientCache == nil {
152+
clientCache = ttlcache.NewCache()
153+
clientCache.SetTTL(cacheExpiration)
154+
clientCache.SkipTtlExtensionOnHit(false)
155+
log.V(1).Info("NewClientFromConf: New client cache created", "expiration", cacheExpiration.String())
156+
}
157+
158+
clientCacheKey := generateClientCacheKey(conf)
159+
if client, exists := clientCache.Get(clientCacheKey); exists {
160+
log.V(1).Info("NewClientFromConf: Using a cached client", "APIUrl", conf.APIUrl, "APIKey", conf.APIKey, "cache size", clientCache.Count())
161+
return client.(Client), nil
146162
}
147163

148164
verifySSL := true
@@ -157,7 +173,8 @@ func NewClientFromConf(conf Config) (Client, error) {
157173
c.cs = cloudstack.NewAsyncClient(conf.APIUrl, conf.APIKey, conf.SecretKey, verifySSL)
158174
c.csAsync = cloudstack.NewClient(conf.APIUrl, conf.APIKey, conf.SecretKey, verifySSL)
159175
c.customMetrics = metrics.NewCustomMetrics()
160-
clientCache[conf] = c
176+
clientCache.Set(clientCacheKey, c)
177+
log.V(1).Info("NewClientFromConf: Created a new client and added to the client cache", "APIUrl", conf.APIUrl, "APIKey", conf.APIKey, "cache size", clientCache.Count())
161178

162179
return c, nil
163180
}
@@ -184,3 +201,7 @@ func NewClientFromCSAPIClient(cs *cloudstack.CloudStackClient) Client {
184201
c := &client{cs: cs, csAsync: cs, customMetrics: metrics.NewCustomMetrics()}
185202
return c
186203
}
204+
205+
func generateClientCacheKey(conf Config) string {
206+
return fmt.Sprintf("%+v", conf)
207+
}

0 commit comments

Comments
 (0)