@@ -14,6 +14,7 @@ import (
14
14
"fmt"
15
15
"github.com/google/uuid"
16
16
"google.golang.org/grpc"
17
+ "google.golang.org/grpc/backoff"
17
18
"google.golang.org/grpc/connectivity"
18
19
"google.golang.org/grpc/credentials"
19
20
"google.golang.org/grpc/credentials/insecure"
@@ -197,12 +198,17 @@ func (s *Session) ID() string {
197
198
198
199
// Close closes a connection.
199
200
func (s * Session ) Close () {
200
- s .maps = make (map [string ]interface {}, 0 )
201
- s .caches = make (map [string ]interface {}, 0 )
202
- err := s .conn .Close ()
203
- s .closed = true
204
- if err != nil {
205
- log .Printf ("Unable to close session %s %v" , s .sessionID , err )
201
+ if ! s .closed {
202
+ s .maps = make (map [string ]interface {}, 0 )
203
+ s .caches = make (map [string ]interface {}, 0 )
204
+ err := s .conn .Close ()
205
+ s .closed = true
206
+ s .dispatch (Closed , func () SessionLifecycleEvent {
207
+ return newSessionLifecycleEvent (s , Closed )
208
+ })
209
+ if err != nil {
210
+ log .Printf ("Unable to close session %s %v" , s .sessionID , err )
211
+ }
206
212
}
207
213
}
208
214
@@ -245,6 +251,17 @@ func (s *Session) ensureConnection() error {
245
251
}
246
252
s .dialOptions = append (s .dialOptions , tlsOpt )
247
253
254
+ connOpt := grpc .WithConnectParams (grpc.ConnectParams {
255
+ Backoff : backoff.Config {
256
+ BaseDelay : 1.0 * time .Second ,
257
+ Multiplier : 1.1 ,
258
+ Jitter : 0.0 ,
259
+ MaxDelay : 3.0 * time .Second ,
260
+ },
261
+ MinConnectTimeout : 10 * time .Second ,
262
+ })
263
+ s .dialOptions = append (s .dialOptions , connOpt )
264
+
248
265
s .mutex .Lock ()
249
266
locked = true
250
267
@@ -268,10 +285,11 @@ func (s *Session) ensureConnection() error {
268
285
// refer: https://grpc.github.io/grpc/core/md_doc_connectivity-semantics-and-api.html
269
286
go func (session * Session ) {
270
287
var (
271
- firstConnect = true
272
- connected = false
273
- ctx = context .Background ()
274
- lastState = session .conn .GetState ()
288
+ firstConnect = true
289
+ connected = false
290
+ ctx = context .Background ()
291
+ lastState = session .conn .GetState ()
292
+ disconnectTime int64 = 0
275
293
)
276
294
277
295
for {
@@ -285,40 +303,52 @@ func (s *Session) ensureConnection() error {
285
303
session .debug ("connection:" , lastState , "=>" , newState )
286
304
287
305
if newState == connectivity .Shutdown {
288
- log .Printf ("closed session %v" , s .sessionID )
289
- s .dispatch (Closed , func () SessionLifecycleEvent {
290
- return newSessionLifecycleEvent (session , Closed )
291
- })
292
- session .closed = true
306
+ log .Printf ("closed session %v" , session .sessionID )
307
+ session .Close ()
293
308
return
294
309
}
295
310
296
311
if newState == connectivity .Ready {
297
312
if ! firstConnect && ! connected {
313
+ disconnectTime = 0
298
314
log .Printf ("session: %s re-connected to address %s" , session .sessionID , session .sessOpts .Address )
299
- s .dispatch (Reconnected , func () SessionLifecycleEvent {
315
+ session .dispatch (Reconnected , func () SessionLifecycleEvent {
300
316
return newSessionLifecycleEvent (session , Reconnected )
301
317
})
302
318
session .closed = false
303
319
connected = true
304
320
} else if firstConnect && ! connected {
305
321
firstConnect = false
306
322
connected = true
307
- s .hasConnected = true
323
+ session .hasConnected = true
308
324
log .Printf ("session: %s connected to address %s" , session .sessionID , session .sessOpts .Address )
309
- s .dispatch (Connected , func () SessionLifecycleEvent {
325
+ session .dispatch (Connected , func () SessionLifecycleEvent {
310
326
return newSessionLifecycleEvent (session , Connected )
311
327
})
312
328
}
313
329
} else {
314
330
if connected {
331
+ disconnectTime = - 1
315
332
log .Printf ("session: %s disconnected from address %s" , session .sessionID , session .sessOpts .Address )
316
- s .dispatch (Disconnected , func () SessionLifecycleEvent {
333
+ session .dispatch (Disconnected , func () SessionLifecycleEvent {
317
334
return newSessionLifecycleEvent (session , Disconnected )
318
335
})
319
336
connected = false
320
337
}
321
338
339
+ if disconnectTime != 0 {
340
+ if disconnectTime == - 1 {
341
+ disconnectTime = time .Now ().UnixMilli ()
342
+ } else {
343
+ waited := time .Now ().UnixMilli () - disconnectTime
344
+ if waited >= session .GetSessionTimeout ().Milliseconds () {
345
+ log .Printf ("session: %s unable to reconnect within [%s]. Closing session." , session .sessionID , session .GetSessionTimeout ().String ())
346
+ session .Close ()
347
+ return
348
+ }
349
+ }
350
+ }
351
+
322
352
// trigger a reconnection on state change
323
353
if newState != connectivity .Connecting {
324
354
conn .Connect ()
0 commit comments