@@ -20,6 +20,7 @@ import (
2020 "fmt"
2121 "strings"
2222 "sync"
23+ "sync/atomic"
2324 "time"
2425
2526 "github.com/coreos/go-semver/semver"
@@ -78,8 +79,7 @@ type Client struct {
7879
7980 callOpts []grpc.CallOption
8081
81- lgMu * sync.RWMutex
82- lg * zap.Logger
82+ lg atomic.Pointer [zap.Logger ]
8383}
8484
8585// New creates a new etcdv3 client from a given configuration.
@@ -96,12 +96,12 @@ func New(cfg Config) (*Client, error) {
9696// service interface implementations and do not need connection management.
9797func NewCtxClient (ctx context.Context , opts ... Option ) * Client {
9898 cctx , cancel := context .WithCancel (ctx )
99- c := & Client {ctx : cctx , cancel : cancel , lgMu : new (sync. RWMutex ), epMu : new (sync.RWMutex )}
99+ c := & Client {ctx : cctx , cancel : cancel , epMu : new (sync.RWMutex )}
100100 for _ , opt := range opts {
101101 opt (c )
102102 }
103- if c .lg == nil {
104- c .lg = zap .NewNop ()
103+ if c .lg . Load () == nil {
104+ c .lg . Store ( zap .NewNop () )
105105 }
106106 return c
107107}
@@ -122,7 +122,7 @@ func NewFromURLs(urls []string) (*Client, error) {
122122// WithZapLogger is a NewCtxClient option that overrides the logger
123123func WithZapLogger (lg * zap.Logger ) Option {
124124 return func (c * Client ) {
125- c .lg = lg
125+ c .lg . Store ( lg )
126126 }
127127}
128128
@@ -133,19 +133,14 @@ func WithZapLogger(lg *zap.Logger) Option {
133133// Does not changes grpcLogger, that can be explicitly configured
134134// using grpc_zap.ReplaceGrpcLoggerV2(..) method.
135135func (c * Client ) WithLogger (lg * zap.Logger ) * Client {
136- c .lgMu .Lock ()
137- c .lg = lg
138- c .lgMu .Unlock ()
136+ c .lg .Store (lg )
139137 return c
140138}
141139
142140// GetLogger gets the logger.
143141// NOTE: This method is for internal use of etcd-client library and should not be used as general-purpose logger.
144142func (c * Client ) GetLogger () * zap.Logger {
145- c .lgMu .RLock ()
146- l := c .lg
147- c .lgMu .RUnlock ()
148- return l
143+ return c .lg .Load ()
149144}
150145
151146// Close shuts down the client's etcd connections.
@@ -205,7 +200,7 @@ func (c *Client) Sync(ctx context.Context) error {
205200 return len (eps ) > 0 , nil
206201 })
207202 c .SetEndpoints (eps ... )
208- c .lg .Debug ("set etcd endpoints by autoSync" , zap .Strings ("endpoints" , eps ))
203+ c .GetLogger () .Debug ("set etcd endpoints by autoSync" , zap .Strings ("endpoints" , eps ))
209204 return nil
210205}
211206
@@ -223,7 +218,7 @@ func (c *Client) autoSync() {
223218 err := c .Sync (ctx )
224219 cancel ()
225220 if err != nil && ! errors .Is (err , c .ctx .Err ()) {
226- c .lg .Info ("Auto sync endpoints failed." , zap .Error (err ))
221+ c .GetLogger () .Info ("Auto sync endpoints failed." , zap .Error (err ))
227222 }
228223 }
229224 }
@@ -402,23 +397,24 @@ func newClient(cfg *Config) (*Client, error) {
402397 cancel : cancel ,
403398 epMu : new (sync.RWMutex ),
404399 callOpts : defaultCallOpts ,
405- lgMu : new (sync.RWMutex ),
406400 }
407401
408402 var err error
403+ var lg * zap.Logger
409404 if cfg .Logger != nil {
410- client . lg = cfg .Logger
405+ lg = cfg .Logger
411406 } else if cfg .LogConfig != nil {
412- client . lg , err = cfg .LogConfig .Build ()
407+ lg , err = cfg .LogConfig .Build ()
413408 } else {
414- client . lg , err = logutil .CreateDefaultZapLogger (etcdClientDebugLevel ())
415- if client . lg != nil {
416- client . lg = client . lg .Named ("etcd-client" )
409+ lg , err = logutil .CreateDefaultZapLogger (etcdClientDebugLevel ())
410+ if lg != nil {
411+ lg = lg .Named ("etcd-client" )
417412 }
418413 }
419414 if err != nil {
420415 return nil , err
421416 }
417+ client .lg .Store (lg )
422418
423419 if cfg .Username != "" && cfg .Password != "" {
424420 client .Username = cfg .Username
@@ -508,10 +504,10 @@ func (c *Client) roundRobinQuorumBackoff(waitBetween time.Duration, jitterFracti
508504 n := uint (len (c .Endpoints ()))
509505 quorum := (n / 2 + 1 )
510506 if attempt % quorum == 0 {
511- c .lg .Debug ("backoff" , zap .Uint ("attempt" , attempt ), zap .Uint ("quorum" , quorum ), zap .Duration ("waitBetween" , waitBetween ), zap .Float64 ("jitterFraction" , jitterFraction ))
507+ c .GetLogger () .Debug ("backoff" , zap .Uint ("attempt" , attempt ), zap .Uint ("quorum" , quorum ), zap .Duration ("waitBetween" , waitBetween ), zap .Float64 ("jitterFraction" , jitterFraction ))
512508 return jitterUp (waitBetween , jitterFraction )
513509 }
514- c .lg .Debug ("backoff skipped" , zap .Uint ("attempt" , attempt ), zap .Uint ("quorum" , quorum ))
510+ c .GetLogger () .Debug ("backoff skipped" , zap .Uint ("attempt" , attempt ), zap .Uint ("quorum" , quorum ))
515511 return 0
516512 }
517513}
0 commit comments