1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package cloudsql
16
17 import (
18 "context"
19 "crypto/rsa"
20 "sync"
21 "time"
22
23 "cloud.google.com/go/cloudsqlconn/debug"
24 "cloud.google.com/go/cloudsqlconn/instance"
25 "golang.org/x/oauth2"
26 sqladmin "google.golang.org/api/sqladmin/v1beta4"
27 )
28
29
30
31 type LazyRefreshCache struct {
32 connName instance.ConnName
33 logger debug.ContextLogger
34 key *rsa.PrivateKey
35 r refresher
36 mu sync.Mutex
37 useIAMAuthNDial bool
38 needsRefresh bool
39 cached ConnectionInfo
40 }
41
42
43 func NewLazyRefreshCache(
44 cn instance.ConnName,
45 l debug.ContextLogger,
46 client *sqladmin.Service,
47 key *rsa.PrivateKey,
48 _ time.Duration,
49 ts oauth2.TokenSource,
50 dialerID string,
51 useIAMAuthNDial bool,
52 ) *LazyRefreshCache {
53 return &LazyRefreshCache{
54 connName: cn,
55 logger: l,
56 key: key,
57 r: newRefresher(
58 l,
59 client,
60 ts,
61 dialerID,
62 ),
63 useIAMAuthNDial: useIAMAuthNDial,
64 }
65 }
66
67
68
69
70
71 func (c *LazyRefreshCache) ConnectionInfo(
72 ctx context.Context,
73 ) (ConnectionInfo, error) {
74 c.mu.Lock()
75 defer c.mu.Unlock()
76
77 now := time.Now().UTC()
78
79
80 exp := c.cached.Expiration.UTC().Add(-refreshBuffer)
81 if !c.needsRefresh && now.Before(exp) {
82 c.logger.Debugf(
83 ctx,
84 "[%v] Connection info is still valid, using cached info",
85 c.connName.String(),
86 )
87 return c.cached, nil
88 }
89
90 c.logger.Debugf(
91 ctx,
92 "[%v] Connection info refresh operation started",
93 c.connName.String(),
94 )
95 ci, err := c.r.ConnectionInfo(ctx, c.connName, c.key, c.useIAMAuthNDial)
96 if err != nil {
97 c.logger.Debugf(
98 ctx,
99 "[%v] Connection info refresh operation failed, err = %v",
100 c.connName.String(),
101 err,
102 )
103 return ConnectionInfo{}, err
104 }
105 c.logger.Debugf(
106 ctx,
107 "[%v] Connection info refresh operation complete",
108 c.connName.String(),
109 )
110 c.logger.Debugf(
111 ctx,
112 "[%v] Current certificate expiration = %v",
113 c.connName.String(),
114 ci.Expiration.UTC().Format(time.RFC3339),
115 )
116 c.cached = ci
117 c.needsRefresh = false
118 return ci, nil
119 }
120
121
122
123 func (c *LazyRefreshCache) UpdateRefresh(useIAMAuthNDial *bool) {
124 c.mu.Lock()
125 defer c.mu.Unlock()
126 if useIAMAuthNDial != nil && *useIAMAuthNDial != c.useIAMAuthNDial {
127 c.useIAMAuthNDial = *useIAMAuthNDial
128 c.needsRefresh = true
129 }
130 }
131
132
133
134 func (c *LazyRefreshCache) ForceRefresh() {
135 c.mu.Lock()
136 defer c.mu.Unlock()
137 c.needsRefresh = true
138 }
139
140
141
142 func (c *LazyRefreshCache) Close() error {
143 return nil
144 }
145
View as plain text