Skip to content

Commit 99fd522

Browse files
committed
Add client package
Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@gmail.com>
1 parent de8cad7 commit 99fd522

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

client/client.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package client
2+
3+
import (
4+
"sync"
5+
6+
"github.com/hashicorp/golang-lru/v2"
7+
8+
"k8s.io/client-go/rest"
9+
"sigs.k8s.io/controller-runtime/pkg/client"
10+
11+
"github.com/kcp-dev/logicalcluster/v3"
12+
)
13+
14+
// ClusterClient is a cluster-aware client.
15+
type ClusterClient interface {
16+
// Cluster returns the client for the given cluster.
17+
Cluster(cluster logicalcluster.Path) (client.Client, error)
18+
}
19+
20+
// clusterClient is a multi-cluster-aware client.
21+
type clusterClient struct {
22+
baseConfig *rest.Config
23+
opts client.Options
24+
25+
lock sync.RWMutex
26+
cache *lru.Cache[logicalcluster.Path, client.Client]
27+
}
28+
29+
// New creates a new cluster-aware client.
30+
func New(cfg *rest.Config, options client.Options) (ClusterClient, error) {
31+
ca, err := lru.New[logicalcluster.Path, client.Client](100)
32+
if err != nil {
33+
return nil, err
34+
}
35+
return &clusterClient{
36+
opts: options,
37+
baseConfig: cfg,
38+
cache: ca,
39+
}, nil
40+
}
41+
42+
func (c *clusterClient) Cluster(cluster logicalcluster.Path) (client.Client, error) {
43+
// quick path
44+
c.lock.RLock()
45+
cli, ok := c.cache.Get(cluster)
46+
c.lock.RUnlock()
47+
if ok {
48+
return cli, nil
49+
}
50+
51+
// slow path
52+
c.lock.Lock()
53+
defer c.lock.Unlock()
54+
if cli, ok := c.cache.Get(cluster); ok {
55+
return cli, nil
56+
}
57+
58+
// cache miss
59+
cfg := rest.CopyConfig(c.baseConfig)
60+
cfg.Host = cfg.Host + cluster.RequestPath()
61+
cli, err := client.New(cfg, c.opts)
62+
if err != nil {
63+
return nil, err
64+
}
65+
c.cache.Add(cluster, cli)
66+
return cli, nil
67+
}

0 commit comments

Comments
 (0)