@@ -30,22 +30,24 @@ var globalConnectionID uint64 = 1
30
30
func nextConnectionID () uint64 { return atomic .AddUint64 (& globalConnectionID , 1 ) }
31
31
32
32
type connection struct {
33
- id string
34
- nc net.Conn // When nil, the connection is closed.
35
- addr address.Address
36
- idleTimeout time.Duration
37
- idleDeadline atomic.Value // Stores a time.Time
38
- lifetimeDeadline time.Time
39
- readTimeout time.Duration
40
- writeTimeout time.Duration
41
- desc description.Server
42
- compressor wiremessage.CompressorID
43
- zliblevel int
44
- zstdLevel int
45
- connected int32 // must be accessed using the sync/atomic package
46
- connectDone chan struct {}
47
- connectErr error
48
- config * connectionConfig
33
+ id string
34
+ nc net.Conn // When nil, the connection is closed.
35
+ addr address.Address
36
+ idleTimeout time.Duration
37
+ idleDeadline atomic.Value // Stores a time.Time
38
+ lifetimeDeadline time.Time
39
+ readTimeout time.Duration
40
+ writeTimeout time.Duration
41
+ desc description.Server
42
+ compressor wiremessage.CompressorID
43
+ zliblevel int
44
+ zstdLevel int
45
+ connected int32 // must be accessed using the sync/atomic package
46
+ connectDone chan struct {}
47
+ connectErr error
48
+ config * connectionConfig
49
+ cancelConnectContext context.CancelFunc
50
+ connectContextMade chan struct {}
49
51
50
52
// pool related fields
51
53
pool * pool
@@ -68,14 +70,15 @@ func newConnection(ctx context.Context, addr address.Address, opts ...Connection
68
70
id := fmt .Sprintf ("%s[-%d]" , addr , nextConnectionID ())
69
71
70
72
c := & connection {
71
- id : id ,
72
- addr : addr ,
73
- idleTimeout : cfg .idleTimeout ,
74
- lifetimeDeadline : lifetimeDeadline ,
75
- readTimeout : cfg .readTimeout ,
76
- writeTimeout : cfg .writeTimeout ,
77
- connectDone : make (chan struct {}),
78
- config : cfg ,
73
+ id : id ,
74
+ addr : addr ,
75
+ idleTimeout : cfg .idleTimeout ,
76
+ lifetimeDeadline : lifetimeDeadline ,
77
+ readTimeout : cfg .readTimeout ,
78
+ writeTimeout : cfg .writeTimeout ,
79
+ connectDone : make (chan struct {}),
80
+ config : cfg ,
81
+ connectContextMade : make (chan struct {}),
79
82
}
80
83
atomic .StoreInt32 (& c .connected , initialized )
81
84
@@ -85,12 +88,14 @@ func newConnection(ctx context.Context, addr address.Address, opts ...Connection
85
88
// connect handles the I/O for a connection. It will dial, configure TLS, and perform
86
89
// initialization handshakes.
87
90
func (c * connection ) connect (ctx context.Context ) {
88
-
89
91
if ! atomic .CompareAndSwapInt32 (& c .connected , initialized , connected ) {
90
92
return
91
93
}
92
94
defer close (c .connectDone )
93
95
96
+ ctx , c .cancelConnectContext = context .WithCancel (ctx )
97
+ close (c .connectContextMade )
98
+
94
99
var err error
95
100
c .nc , err = c .config .dialer .DialContext (ctx , c .addr .Network (), c .addr .String ())
96
101
if err != nil {
@@ -178,6 +183,11 @@ func (c *connection) wait() error {
178
183
return c .connectErr
179
184
}
180
185
186
+ func (c * connection ) closeConnectContext () {
187
+ <- c .connectContextMade
188
+ c .cancelConnectContext ()
189
+ }
190
+
181
191
func (c * connection ) writeWireMessage (ctx context.Context , wm []byte ) error {
182
192
var err error
183
193
if atomic .LoadInt32 (& c .connected ) != connected {
0 commit comments