@@ -32,13 +32,10 @@ const (
3232 keepAlivePeriod = time .Minute
3333)
3434
35- var (
36- // errNotCached is returned when the instance was not found in the Client's
37- // cache. It is an internal detail and is not actually ever returned to the
38- // user.
39- errNotCached = errors .New ("instance was not found in cache" )
40- refreshCertBuffer = 5 * time .Minute
41- )
35+ // errNotCached is returned when the instance was not found in the Client's
36+ // cache. It is an internal detail and is not actually ever returned to the
37+ // user.
38+ var errNotCached = errors .New ("instance was not found in cache" )
4239
4340// Conn represents a connection from a client to a specific instance.
4441type Conn struct {
@@ -81,12 +78,9 @@ type Client struct {
8178
8279 // The cfgCache holds the most recent connection configuration keyed by
8380 // instance. Relevant functions are refreshCfg and cachedCfg. It is
84- // protected by cacheL .
81+ // protected by cfgL .
8582 cfgCache map [string ]cacheEntry
86- cacheL sync.Mutex
87-
88- // refreshCfgL prevents multiple goroutines from contacting the Cloud SQL API at once.
89- refreshCfgL sync.Mutex
83+ cfgL sync.RWMutex
9084
9185 // MaxConnections is the maximum number of connections to establish
9286 // before refusing new connections. 0 means no limit.
@@ -156,39 +150,32 @@ func (c *Client) handleConn(conn Conn) {
156150// address as well as construct a new tls.Config to connect to the instance. It
157151// caches the result.
158152func (c * Client ) refreshCfg (instance string ) (addr string , cfg * tls.Config , err error ) {
159- c .refreshCfgL .Lock ()
160- defer c .refreshCfgL .Unlock ()
153+ c .cfgL .Lock ()
154+ defer c .cfgL .Unlock ()
161155
162156 throttle := c .RefreshCfgThrottle
163157 if throttle == 0 {
164158 throttle = DefaultRefreshCfgThrottle
165159 }
166160
167- c .cacheL .Lock ()
168- if c .cfgCache == nil {
169- c .cfgCache = make (map [string ]cacheEntry )
170- }
171- old , oldok := c .cfgCache [instance ]
172- c .cacheL .Unlock ()
173-
174- if oldok && time .Since (old .lastRefreshed ) < throttle {
161+ if old := c .cfgCache [instance ]; time .Since (old .lastRefreshed ) < throttle {
175162 logging .Errorf ("Throttling refreshCfg(%s): it was only called %v ago" , instance , time .Since (old .lastRefreshed ))
176163 // Refresh was called too recently, just reuse the result.
177164 return old .addr , old .cfg , old .err
178165 }
179166
167+ if c .cfgCache == nil {
168+ c .cfgCache = make (map [string ]cacheEntry )
169+ }
170+
180171 defer func () {
181- if err != nil && oldok {
182- return
183- }
184- c .cacheL .Lock ()
185172 c .cfgCache [instance ] = cacheEntry {
186173 lastRefreshed : time .Now (),
187- err : err ,
188- addr : addr ,
189- cfg : cfg ,
174+
175+ err : err ,
176+ addr : addr ,
177+ cfg : cfg ,
190178 }
191- c .cacheL .Unlock ()
192179 }()
193180
194181 mycert , err := c .Certs .Local (instance )
@@ -208,26 +195,13 @@ func (c *Client) refreshCfg(instance string) (addr string, cfg *tls.Config, err
208195 Certificates : []tls.Certificate {mycert },
209196 RootCAs : certs ,
210197 }
211-
212- // Refresh cert 5 minutes before it expires.
213- timeToRefresh := cfg .Certificates [0 ].Leaf .NotAfter .Sub (time .Now ()) - refreshCertBuffer
214- if timeToRefresh > 0 {
215- go func () {
216- <- time .After (timeToRefresh )
217- logging .Verbosef ("Cert for instance %s will expire soon, refreshing now." , instance )
218- if _ , _ , err := c .refreshCfg (instance ); err != nil {
219- logging .Errorf ("couldn't connect to %q: %v" , instance , err )
220- }
221- }()
222- }
223-
224198 return fmt .Sprintf ("%s:%d" , addr , c .Port ), cfg , nil
225199}
226200
227201func (c * Client ) cachedCfg (instance string ) (string , * tls.Config ) {
228- c .cacheL . Lock ()
202+ c .cfgL . RLock ()
229203 ret , ok := c .cfgCache [instance ]
230- c .cacheL . Unlock ()
204+ c .cfgL . RUnlock ()
231205
232206 // Don't waste time returning an expired/invalid cert.
233207 if ! ok || ret .err != nil || time .Now ().After (ret .cfg .Certificates [0 ].Leaf .NotAfter ) {
@@ -251,7 +225,6 @@ func (c *Client) Dial(instance string) (net.Conn, error) {
251225 if err != nil {
252226 return nil , err
253227 }
254-
255228 return c .tryConnect (addr , cfg )
256229}
257230
0 commit comments