@@ -18,15 +18,19 @@ package cloud
18
18
19
19
import (
20
20
"bytes"
21
+ "fmt"
21
22
"io"
22
23
"os"
23
24
"sync"
25
+ "time"
24
26
25
27
corev1 "k8s.io/api/core/v1"
28
+ ctrl "sigs.k8s.io/controller-runtime"
26
29
27
30
"gopkg.in/yaml.v3"
28
31
"sigs.k8s.io/cluster-api-provider-cloudstack/pkg/metrics"
29
32
33
+ "github.com/ReneKroon/ttlcache"
30
34
"github.com/apache/cloudstack-go/v2/cloudstack"
31
35
"github.com/pkg/errors"
32
36
)
@@ -67,8 +71,11 @@ type SecretConfig struct {
67
71
StringData Config `yaml:"stringData"`
68
72
}
69
73
70
- var clientCache = map [ Config ] * client {}
74
+ var clientCache * ttlcache. Cache
71
75
var cacheMutex sync.Mutex
76
+ var log = ctrl .Log .WithName ("Client" )
77
+
78
+ const cacheExpiration = time .Duration (1 * time .Minute )
72
79
73
80
// UnmarshalAllSecretConfigs parses a yaml document for each secret.
74
81
func UnmarshalAllSecretConfigs (in []byte , out * []SecretConfig ) error {
@@ -141,8 +148,17 @@ func NewClientFromConf(conf Config) (Client, error) {
141
148
cacheMutex .Lock ()
142
149
defer cacheMutex .Unlock ()
143
150
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
146
162
}
147
163
148
164
verifySSL := true
@@ -157,7 +173,8 @@ func NewClientFromConf(conf Config) (Client, error) {
157
173
c .cs = cloudstack .NewAsyncClient (conf .APIUrl , conf .APIKey , conf .SecretKey , verifySSL )
158
174
c .csAsync = cloudstack .NewClient (conf .APIUrl , conf .APIKey , conf .SecretKey , verifySSL )
159
175
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 ())
161
178
162
179
return c , nil
163
180
}
@@ -184,3 +201,7 @@ func NewClientFromCSAPIClient(cs *cloudstack.CloudStackClient) Client {
184
201
c := & client {cs : cs , csAsync : cs , customMetrics : metrics .NewCustomMetrics ()}
185
202
return c
186
203
}
204
+
205
+ func generateClientCacheKey (conf Config ) string {
206
+ return fmt .Sprintf ("%+v" , conf )
207
+ }
0 commit comments