/
deduplicating_client_factory.go
47 lines (38 loc) · 1.3 KB
/
deduplicating_client_factory.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package grpc
import (
"sync"
configuration "github.com/buildbarn/bb-storage/pkg/proto/configuration/grpc"
"google.golang.org/grpc"
"google.golang.org/protobuf/encoding/prototext"
)
type deduplicatingClientFactory struct {
base ClientFactory
lock sync.Mutex
clients map[string]grpc.ClientConnInterface
}
// NewDeduplicatingClientFactory creates a decorator for ClientFactory
// that deduplicates requests for creating gRPC clients. This means that
// clients for identical endpoints, having identical TLS settings, etc.
// will not cause multiple connections to be established.
func NewDeduplicatingClientFactory(base ClientFactory) ClientFactory {
return &deduplicatingClientFactory{
base: base,
clients: map[string]grpc.ClientConnInterface{},
}
}
func (cf *deduplicatingClientFactory) NewClientFromConfiguration(configuration *configuration.ClientConfiguration) (grpc.ClientConnInterface, error) {
key := prototext.Format(configuration)
cf.lock.Lock()
defer cf.lock.Unlock()
// Attempt to return an existing client.
if client, ok := cf.clients[key]; ok {
return client, nil
}
// Create a new client, as it has a different configuration.
client, err := cf.base.NewClientFromConfiguration(configuration)
if err != nil {
return nil, err
}
cf.clients[key] = client
return client, nil
}