@@ -18,31 +18,58 @@ import (
1818
1919var timeout = time .Minute * 5
2020
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
2525}
2626
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
2930 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+
3436 logFirstError .Do (func () {
3537 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 ))
3739 }
3840 })
41+
3942 return
4043 },
4144 shouldRetry ,
4245 backoff .NewExponentialWithJitter (time .Millisecond * 128 , time .Minute * 1 ),
4346 timeout ,
4447 ), "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
4673}
4774
4875func shouldRetry (err error ) bool {
@@ -68,7 +95,13 @@ func shouldRetry(err error) bool {
6895}
6996
7097func 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 })
7299 // TODO(el): Don't discard but hide?
73100 _ = mysql .SetLogger (log .New (ioutil .Discard , "" , 0 ))
74101}
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