@@ -23,19 +23,26 @@ type Pool struct {
2323
2424// Options for Pool.
2525type Options struct {
26- ClientOptions ch.Options
27- MaxConnLifetime time.Duration
28- MaxConnIdleTime time.Duration
29- MaxConns int32
30- MinConns int32
31- HealthCheckPeriod time.Duration
26+ ClientOptions ch.Options
27+ MaxConnLifetime time.Duration
28+ MaxConnIdleTime time.Duration
29+ MaxConns int32
30+ MinConns int32
31+ HealthCheckPeriod time.Duration
32+ HealthCheckFunc func (ctx context.Context , client * ch.Client ) error
33+ HealthCheckTimeout time.Duration
34+ }
35+
36+ func DefaultHealthCheckFunc (ctx context.Context , client * ch.Client ) error {
37+ return client .Ping (ctx )
3238}
3339
3440// Defaults for pool.
3541const (
36- DefaultMaxConnLifetime = time .Hour
37- DefaultMaxConnIdleTime = time .Minute * 30
38- DefaultHealthCheckPeriod = time .Minute
42+ DefaultMaxConnLifetime = time .Hour
43+ DefaultMaxConnIdleTime = time .Minute * 30
44+ DefaultHealthCheckPeriod = time .Minute
45+ DefaultHealthCheckTimeout = time .Second
3946)
4047
4148func (o * Options ) setDefaults () {
@@ -51,6 +58,12 @@ func (o *Options) setDefaults() {
5158 if o .HealthCheckPeriod == 0 {
5259 o .HealthCheckPeriod = DefaultHealthCheckPeriod
5360 }
61+ if o .HealthCheckFunc == nil {
62+ o .HealthCheckFunc = DefaultHealthCheckFunc
63+ }
64+ if o .HealthCheckTimeout == 0 {
65+ o .HealthCheckTimeout = DefaultHealthCheckTimeout
66+ }
5467}
5568
5669// Dial returns a pool of connections to ClickHouse.
@@ -163,15 +176,34 @@ func (p *Pool) checkIdleConnsHealth() {
163176 resources := p .pool .AcquireAllIdle ()
164177
165178 now := time .Now ()
179+ wg := sync.WaitGroup {}
166180 for _ , res := range resources {
167- if now .Sub (res .CreationTime ()) > p .options .MaxConnLifetime {
168- res .Destroy ()
169- } else if res .IdleDuration () > p .options .MaxConnIdleTime {
170- res .Destroy ()
171- } else {
181+ res := res
182+ wg .Add (1 )
183+ go func () {
184+ if now .Sub (res .CreationTime ()) > p .options .MaxConnLifetime {
185+ res .Destroy ()
186+ return
187+ }
188+
189+ if res .IdleDuration () > p .options .MaxConnIdleTime {
190+ res .Destroy ()
191+ return
192+ }
193+
194+ if p .options .HealthCheckFunc != nil {
195+ ctx , cancel := context .WithTimeout (context .Background (), p .options .HealthCheckTimeout )
196+ defer cancel ()
197+ if err := p .options .HealthCheckFunc (ctx , res .Value ().client ); err != nil {
198+ res .Destroy ()
199+ return
200+ }
201+ res .Value ().lastHealthCheckTimestamp = now
202+ }
172203 res .ReleaseUnused ()
173- }
204+ }()
174205 }
206+ wg .Wait ()
175207}
176208
177209func (p * Pool ) checkMinConns () {
0 commit comments