mirror of
https://github.com/Icinga/icingadb.git
synced 2026-05-28 04:35:54 -04:00
commit
f8315deb9c
1 changed files with 46 additions and 13 deletions
|
|
@ -18,31 +18,58 @@ import (
|
|||
|
||||
var timeout = time.Minute * 5
|
||||
|
||||
// TODO(el): Support DriverContext.
|
||||
type Driver struct {
|
||||
Driver driver.Driver
|
||||
Logger *zap.SugaredLogger
|
||||
// RetryConnector wraps driver.Connector with retry logic.
|
||||
type RetryConnector struct {
|
||||
driver.Connector
|
||||
driver Driver
|
||||
}
|
||||
|
||||
// TODO(el): Test DNS.
|
||||
func (d Driver) Open(dsn string) (c driver.Conn, err error) {
|
||||
// Connect implements part of the driver.Connector interface.
|
||||
func (c RetryConnector) Connect(ctx context.Context) (driver.Conn, error) {
|
||||
var conn driver.Conn
|
||||
var logFirstError sync.Once
|
||||
err = errors.Wrap(retry.WithBackoff(
|
||||
context.Background(),
|
||||
func(context.Context) (err error) {
|
||||
c, err = d.Driver.Open(dsn)
|
||||
err := errors.Wrap(retry.WithBackoff(
|
||||
ctx,
|
||||
func(ctx context.Context) (err error) {
|
||||
conn, err = c.Connector.Connect(ctx)
|
||||
|
||||
logFirstError.Do(func() {
|
||||
if err != nil {
|
||||
d.Logger.Warnw("Can't connect to database. Retrying", zap.Error(err))
|
||||
c.driver.Logger.Warnw("Can't connect to database. Retrying", zap.Error(err))
|
||||
}
|
||||
})
|
||||
|
||||
return
|
||||
},
|
||||
shouldRetry,
|
||||
backoff.NewExponentialWithJitter(time.Millisecond*128, time.Minute*1),
|
||||
timeout,
|
||||
), "can't connect to database")
|
||||
return
|
||||
return conn, err
|
||||
}
|
||||
|
||||
// Driver implements part of the driver.Connector interface.
|
||||
func (c RetryConnector) Driver() driver.Driver {
|
||||
return c.driver
|
||||
}
|
||||
|
||||
// Driver wraps a driver.Driver that also must implement driver.DriverContext with logging capabilities and provides our RetryConnector.
|
||||
type Driver struct {
|
||||
ctxDriver
|
||||
Logger *zap.SugaredLogger
|
||||
}
|
||||
|
||||
// OpenConnector implements the DriverContext interface.
|
||||
func (d Driver) OpenConnector(name string) (driver.Connector, error) {
|
||||
c, err := d.ctxDriver.OpenConnector(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &RetryConnector{
|
||||
driver: d,
|
||||
Connector: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func shouldRetry(err error) bool {
|
||||
|
|
@ -68,7 +95,13 @@ func shouldRetry(err error) bool {
|
|||
}
|
||||
|
||||
func Register(logger *zap.SugaredLogger) {
|
||||
sql.Register("icingadb-mysql", &Driver{Driver: &mysql.MySQLDriver{}, Logger: logger})
|
||||
sql.Register("icingadb-mysql", &Driver{ctxDriver: &mysql.MySQLDriver{}, Logger: logger})
|
||||
// TODO(el): Don't discard but hide?
|
||||
_ = mysql.SetLogger(log.New(ioutil.Discard, "", 0))
|
||||
}
|
||||
|
||||
// ctxDriver helps ensure that we only support drivers that implement driver.Driver and driver.DriverContext.
|
||||
type ctxDriver interface {
|
||||
driver.Driver
|
||||
driver.DriverContext
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue