...
1
18
19 package xdsclient
20
21 import (
22 "fmt"
23 "sync"
24 "sync/atomic"
25 "time"
26
27 "google.golang.org/grpc/internal/envconfig"
28 "google.golang.org/grpc/internal/grpcsync"
29 "google.golang.org/grpc/internal/xds/bootstrap"
30 )
31
32 const (
33 defaultWatchExpiryTimeout = 15 * time.Second
34 defaultIdleAuthorityDeleteTimeout = 5 * time.Minute
35 )
36
37 var (
38
39
40 singletonMu sync.Mutex
41 singletonClient *clientRefCounted
42
43
44
45 singletonClientImplCreateHook = func() {}
46 singletonClientImplCloseHook = func() {}
47 )
48
49
50 var bootstrapNewConfig = bootstrap.NewConfig
51
52 func clientRefCountedClose() {
53 singletonMu.Lock()
54 defer singletonMu.Unlock()
55
56 if singletonClient.decrRef() != 0 {
57 return
58 }
59 singletonClient.clientImpl.close()
60 singletonClientImplCloseHook()
61 singletonClient = nil
62 }
63
64 func newRefCountedWithConfig(fallbackConfig *bootstrap.Config) (XDSClient, func(), error) {
65 singletonMu.Lock()
66 defer singletonMu.Unlock()
67
68 if singletonClient != nil {
69 singletonClient.incrRef()
70 return singletonClient, grpcsync.OnceFunc(clientRefCountedClose), nil
71
72 }
73
74
75 var config *bootstrap.Config
76 if envconfig.XDSBootstrapFileName == "" && envconfig.XDSBootstrapFileContent == "" {
77 if fallbackConfig == nil {
78 return nil, nil, fmt.Errorf("xds: bootstrap env vars are unspecified and provided fallback config is nil")
79 }
80 config = fallbackConfig
81 } else {
82 var err error
83 config, err = bootstrapNewConfig()
84 if err != nil {
85 return nil, nil, fmt.Errorf("xds: failed to read bootstrap file: %v", err)
86 }
87 }
88
89
90 c, err := newWithConfig(config, defaultWatchExpiryTimeout, defaultIdleAuthorityDeleteTimeout)
91 if err != nil {
92 return nil, nil, err
93 }
94 singletonClient = &clientRefCounted{clientImpl: c, refCount: 1}
95 singletonClientImplCreateHook()
96
97 logger.Infof("xDS node ID: %s", config.NodeProto.GetId())
98 return singletonClient, grpcsync.OnceFunc(clientRefCountedClose), nil
99 }
100
101
102
103 type clientRefCounted struct {
104 *clientImpl
105
106 refCount int32
107 }
108
109 func (c *clientRefCounted) incrRef() int32 {
110 return atomic.AddInt32(&c.refCount, 1)
111 }
112
113 func (c *clientRefCounted) decrRef() int32 {
114 return atomic.AddInt32(&c.refCount, -1)
115 }
116
View as plain text