@@ -5,10 +5,13 @@ import (
5
5
"time"
6
6
)
7
7
8
+ const recursionLimit = 8
9
+
8
10
type driversPool struct {
9
- driverFactory * driverFactory
10
- drivers chan * driverWrapper
11
- pingThreshold time.Duration
11
+ driverFactory * driverFactory
12
+ drivers chan * driverWrapper
13
+ pingThreshold time.Duration
14
+ maxIdleLifetime time.Duration
12
15
13
16
isPoolClosedMu sync.RWMutex
14
17
isPoolClosed bool
@@ -19,12 +22,14 @@ func newDriversPool(
19
22
minIdle int ,
20
23
maxIdle int ,
21
24
pingThreshold time.Duration ,
25
+ maxIdleLifetime time.Duration ,
22
26
) (* driversPool , error ) {
23
27
dp := & driversPool {
24
28
driverFactory : df ,
25
29
drivers : make (chan * driverWrapper , maxIdle ),
26
30
27
- pingThreshold : pingThreshold ,
31
+ pingThreshold : pingThreshold ,
32
+ maxIdleLifetime : maxIdleLifetime ,
28
33
29
34
isPoolClosedMu : sync.RWMutex {},
30
35
isPoolClosed : false ,
@@ -55,15 +60,15 @@ func newDriversPool(
55
60
56
61
// put the connection back.
57
62
func (p * driversPool ) put (dw * driverWrapper ) {
58
- if dw .closed {
63
+ if dw .driver . closed {
59
64
return
60
65
}
61
66
62
67
p .isPoolClosedMu .RLock ()
63
68
defer p .isPoolClosedMu .RUnlock ()
64
69
65
70
if p .isPoolClosed {
66
- dw .close ()
71
+ dw .driver . close ()
67
72
68
73
return
69
74
}
@@ -72,8 +77,8 @@ func (p *driversPool) put(dw *driverWrapper) {
72
77
case p .drivers <- dw :
73
78
default :
74
79
// The pool is full.
75
- _ = dw .Quit ()
76
- dw .close ()
80
+ _ = dw .driver . Quit ()
81
+ dw .driver . close ()
77
82
}
78
83
}
79
84
@@ -89,24 +94,36 @@ func (p *driversPool) Get() (*driverWrapper, error) {
89
94
return nil , ErrClosed
90
95
}
91
96
97
+ return p .getNextDriver (0 )
98
+ }
99
+
100
+ func (p * driversPool ) getNextDriver (depth int ) (* driverWrapper , error ) {
101
+ if depth > recursionLimit {
102
+ return p .newDriver ()
103
+ }
104
+
92
105
select {
93
106
case d := <- p .drivers :
94
- if ! d .softPing (p .pingThreshold ) {
95
- d .close ()
107
+ if ! d .checkConn (p .pingThreshold , p . maxIdleLifetime ) {
108
+ d .driver . close ()
96
109
97
- return p .Get ( )
110
+ return p .getNextDriver ( depth + 1 )
98
111
}
99
112
100
113
return d , nil
101
114
default :
102
- d := p .driverFactory .Build ()
115
+ return p .newDriver ()
116
+ }
117
+ }
103
118
104
- if err := d .Connect (); err != nil {
105
- return nil , err
106
- }
119
+ func (p * driversPool ) newDriver () (* driverWrapper , error ) {
120
+ d := p .driverFactory .Build ()
107
121
108
- return p .wrapDriver (d ), nil
122
+ if err := d .Connect (); err != nil {
123
+ return nil , err
109
124
}
125
+
126
+ return p .wrapDriver (d ), nil
110
127
}
111
128
112
129
// Close and quit all connections in the pool.
@@ -117,10 +134,10 @@ func (p *driversPool) Close() {
117
134
118
135
close (p .drivers )
119
136
for dw := range p .drivers {
120
- if ! dw .closed {
121
- _ = dw .Quit ()
137
+ if ! dw .driver . closed {
138
+ _ = dw .driver . Quit ()
122
139
123
- dw .close ()
140
+ dw .driver . close ()
124
141
}
125
142
}
126
143
}
0 commit comments