@@ -18,31 +18,58 @@ import (
18
18
19
19
var timeout = time .Minute * 5
20
20
21
- // TODO(el): Support DriverContext .
22
- type Driver struct {
23
- Driver driver.Driver
24
- Logger * zap. SugaredLogger
21
+ // RetryConnector wraps driver.Connector with retry logic .
22
+ type RetryConnector struct {
23
+ driver.Connector
24
+ driver Driver
25
25
}
26
26
27
- // TODO(el): Test DNS.
28
- func (d Driver ) Open (dsn string ) (c driver.Conn , err error ) {
27
+ // Connect implements part of the driver.Connector interface.
28
+ func (c RetryConnector ) Connect (ctx context.Context ) (driver.Conn , error ) {
29
+ var conn driver.Conn
29
30
var logFirstError sync.Once
30
- err = errors .Wrap (retry .WithBackoff (
31
- context .Background (),
32
- func (context.Context ) (err error ) {
33
- c , err = d .Driver .Open (dsn )
31
+ err := errors .Wrap (retry .WithBackoff (
32
+ ctx ,
33
+ func (ctx context.Context ) (err error ) {
34
+ conn , err = c .Connector .Connect (ctx )
35
+
34
36
logFirstError .Do (func () {
35
37
if err != nil {
36
- d .Logger .Warnw ("Can't connect to database. Retrying" , zap .Error (err ))
38
+ c . driver .Logger .Warnw ("Can't connect to database. Retrying" , zap .Error (err ))
37
39
}
38
40
})
41
+
39
42
return
40
43
},
41
44
shouldRetry ,
42
45
backoff .NewExponentialWithJitter (time .Millisecond * 128 , time .Minute * 1 ),
43
46
timeout ,
44
47
), "can't connect to database" )
45
- return
48
+ return conn , err
49
+ }
50
+
51
+ // Driver implements part of the driver.Connector interface.
52
+ func (c RetryConnector ) Driver () driver.Driver {
53
+ return c .driver
54
+ }
55
+
56
+ // Driver wraps a driver.Driver that also must implement driver.DriverContext with logging capabilities and provides our RetryConnector.
57
+ type Driver struct {
58
+ ctxDriver
59
+ Logger * zap.SugaredLogger
60
+ }
61
+
62
+ // OpenConnector implements the DriverContext interface.
63
+ func (d Driver ) OpenConnector (name string ) (driver.Connector , error ) {
64
+ c , err := d .ctxDriver .OpenConnector (name )
65
+ if err != nil {
66
+ return nil , err
67
+ }
68
+
69
+ return & RetryConnector {
70
+ driver : d ,
71
+ Connector : c ,
72
+ }, nil
46
73
}
47
74
48
75
func shouldRetry (err error ) bool {
@@ -68,7 +95,13 @@ func shouldRetry(err error) bool {
68
95
}
69
96
70
97
func Register (logger * zap.SugaredLogger ) {
71
- sql .Register ("icingadb-mysql" , & Driver {Driver : & mysql.MySQLDriver {}, Logger : logger })
98
+ sql .Register ("icingadb-mysql" , & Driver {ctxDriver : & mysql.MySQLDriver {}, Logger : logger })
72
99
// TODO(el): Don't discard but hide?
73
100
_ = mysql .SetLogger (log .New (ioutil .Discard , "" , 0 ))
74
101
}
102
+
103
+ // ctxDriver helps ensure that we only support drivers that implement driver.Driver and driver.DriverContext.
104
+ type ctxDriver interface {
105
+ driver.Driver
106
+ driver.DriverContext
107
+ }
0 commit comments