Skip to content

Commit f8315de

Browse files
authored
Merge pull request #300 from Icinga/driver-context
Driver context
2 parents 40bbe31 + 7eb55ae commit f8315de

File tree

1 file changed

+46
-13
lines changed

1 file changed

+46
-13
lines changed

pkg/driver/driver.go

+46-13
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,58 @@ import (
1818

1919
var 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

4875
func shouldRetry(err error) bool {
@@ -68,7 +95,13 @@ func shouldRetry(err error) bool {
6895
}
6996

7097
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})
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

Comments
 (0)