@@ -92,12 +92,24 @@ func (d defaultLogger) Report(event ConnLogKind, conn *Connection, v ...interfac
9292 case LogReconnectFailed :
9393 reconnects := v [0 ].(uint )
9494 err := v [1 ].(error )
95- log .Printf ("tarantool: reconnect (%d/%d) to %s failed: %s" ,
96- reconnects , conn .opts .MaxReconnects , conn .Addr (), err )
95+ addr := conn .Addr ()
96+ if addr == nil {
97+ log .Printf ("tarantool: connect (%d/%d) failed: %s" ,
98+ reconnects , conn .opts .MaxReconnects , err )
99+ } else {
100+ log .Printf ("tarantool: reconnect (%d/%d) to %s failed: %s" ,
101+ reconnects , conn .opts .MaxReconnects , addr , err )
102+ }
97103 case LogLastReconnectFailed :
98104 err := v [0 ].(error )
99- log .Printf ("tarantool: last reconnect to %s failed: %s, giving it up" ,
100- conn .Addr (), err )
105+ addr := conn .Addr ()
106+ if addr == nil {
107+ log .Printf ("tarantool: last connect failed: %s, giving it up" ,
108+ err )
109+ } else {
110+ log .Printf ("tarantool: last reconnect to %s failed: %s, giving it up" ,
111+ addr , err )
112+ }
101113 case LogUnexpectedResultId :
102114 header := v [0 ].(Header )
103115 log .Printf ("tarantool: connection %s got unexpected request ID (%d) in response " +
@@ -362,8 +374,20 @@ func Connect(ctx context.Context, dialer Dialer, opts Opts) (conn *Connection, e
362374
363375 conn .cond = sync .NewCond (& conn .mutex )
364376
365- if err = conn .createConnection (ctx ); err != nil {
366- return nil , err
377+ if conn .opts .Reconnect > 0 {
378+ // We don't need these mutex.Lock()/mutex.Unlock() here, but
379+ // runReconnects() expects mutex.Lock() to be set, so it's
380+ // easier to add them instead of reworking runReconnects().
381+ conn .mutex .Lock ()
382+ err = conn .runReconnects (ctx )
383+ conn .mutex .Unlock ()
384+ if err != nil {
385+ return nil , err
386+ }
387+ } else {
388+ if err = conn .connect (ctx ); err != nil {
389+ return nil , err
390+ }
367391 }
368392
369393 go conn .pinger ()
@@ -553,7 +577,7 @@ func pack(h *smallWBuf, enc *msgpack.Encoder, reqid uint32,
553577 return
554578}
555579
556- func (conn * Connection ) createConnection (ctx context.Context ) error {
580+ func (conn * Connection ) connect (ctx context.Context ) error {
557581 var err error
558582 if conn .c == nil && conn .state == connDisconnected {
559583 if err = conn .dial (ctx ); err == nil {
@@ -616,19 +640,30 @@ func (conn *Connection) getDialTimeout() time.Duration {
616640 return dialTimeout
617641}
618642
619- func (conn * Connection ) runReconnects () error {
643+ func (conn * Connection ) runReconnects (ctx context. Context ) error {
620644 dialTimeout := conn .getDialTimeout ()
621645 var reconnects uint
622646 var err error
623647
648+ t := time .NewTicker (conn .opts .Reconnect )
649+ defer t .Stop ()
624650 for conn .opts .MaxReconnects == 0 || reconnects <= conn .opts .MaxReconnects {
625- now := time .Now ()
626-
627- ctx , cancel := context .WithTimeout (context .Background (), dialTimeout )
628- err = conn .createConnection (ctx )
651+ localCtx , cancel := context .WithTimeout (ctx , dialTimeout )
652+ err = conn .connect (localCtx )
629653 cancel ()
630654
631655 if err != nil {
656+ // The error will most likely be the one that Dialer
657+ // returns to us due to the context being cancelled.
658+ // Although this is not guaranteed. For example,
659+ // if the dialer may throw another error before checking
660+ // the context, and the context has already been
661+ // canceled. Or the context was not canceled after
662+ // the error was thrown, but before the context was
663+ // checked here.
664+ if ctx .Err () != nil {
665+ return err
666+ }
632667 if clientErr , ok := err .(ClientError ); ok &&
633668 clientErr .Code == ErrConnectionClosed {
634669 return err
@@ -642,7 +677,12 @@ func (conn *Connection) runReconnects() error {
642677 reconnects ++
643678 conn .mutex .Unlock ()
644679
645- time .Sleep (time .Until (now .Add (conn .opts .Reconnect )))
680+ select {
681+ case <- ctx .Done ():
682+ // Since the context is cancelled, we don't need to do anything.
683+ // Conn.connect() will return the correct error.
684+ case <- t .C :
685+ }
646686
647687 conn .mutex .Lock ()
648688 }
@@ -656,7 +696,7 @@ func (conn *Connection) reconnectImpl(neterr error, c Conn) {
656696 if conn .opts .Reconnect > 0 {
657697 if c == conn .c {
658698 conn .closeConnection (neterr , false )
659- if err := conn .runReconnects (); err != nil {
699+ if err := conn .runReconnects (context . Background () ); err != nil {
660700 conn .closeConnection (err , true )
661701 }
662702 }
0 commit comments