diff --git a/examples/gorm/config/application-gorm.yml b/examples/gorm/config/application-gorm.yml index c54316e..fd6d248 100644 --- a/examples/gorm/config/application-gorm.yml +++ b/examples/gorm/config/application-gorm.yml @@ -10,6 +10,7 @@ gorm: password: Duahbi3GqMmeS7ogPw743xtmsmVFiDIaNwh24BokqC1BnUIah8doCRRhVuIqtWs3tl8nHRNkEWMIbuKAo6GleN4FwSoO56B8HAxqP3Kv8Jr3A6L2bam1bglFJRDx6rRkSuX4zrO3D/35t1YSFdPKf+n2PWIEeEJI6zcULo7UVKA= charset: utf8 parseTime: true + retry_times: 1 loc: Asia/Shanghai config: decrypt: true diff --git a/examples/gorm/config/application-local.yml b/examples/gorm/config/application-local.yml index aaf6101..bc6b928 100644 --- a/examples/gorm/config/application-local.yml +++ b/examples/gorm/config/application-local.yml @@ -5,3 +5,9 @@ server: logging: level: info +# +#gorm: +# host: 10.10.12.14 +# database: demo +# username: root +# password: mN632xQ/rlS3E0r0pGz/bSvbEAoAGQSMSzxc1EmHUdjf6oGhMNtQ1EQmd14+LSMcqnr6Ln1UNoQvzgZMCyqAty4tXVFAxd+h+YABDcf+gBS+b+I4R4iQmxVdbT/FA2OcXiqT4XW0YKHh1KuHw/fBqhn2QwqH2IVIaUzA7689dpw= diff --git a/starter/gorm/autoconfigure_test.go b/starter/gorm/autoconfigure_test.go index 79d9619..c41aee9 100644 --- a/starter/gorm/autoconfigure_test.go +++ b/starter/gorm/autoconfigure_test.go @@ -38,5 +38,5 @@ func TestConfiguration(t *testing.T) { }) repo := conf.Repository() - assert.Equal(t, nil, repo) + assert.NotEqual(t, nil, repo) } diff --git a/starter/gorm/datasource.go b/starter/gorm/datasource.go index 14268b2..6cdefec 100644 --- a/starter/gorm/datasource.go +++ b/starter/gorm/datasource.go @@ -61,32 +61,9 @@ func (d *dataSource) Init(repository Repository) { func (d *dataSource) Open(p *Properties) error { var err error - password := p.Password - if p.Config.Decrypt { - pwd, err := rsa.DecryptBase64([]byte(password), []byte(p.Config.DecryptKey)) - if err == nil { - password = string(pwd) - } - } - loc := strings.Replace(p.Loc, "/", "%2F", -1) - databaseName := strings.Replace(p.Database, "-", "_", -1) - parseTime := "False" - if p.ParseTime { - parseTime = "True" - } - source := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=%v&parseTime=%v&loc=%v", - p.Username, password, p.Host, p.Port, databaseName, p.Charset, parseTime, loc) - - d.repository, err = gorm.Open(p.Type, source) + err = d.Connect(p) if err != nil { - log.Errorf("dataSource connection failed: %v (%v)", err, p) - defer func() { - d.repository.Close() - d.repository = nil - }() return err - } else { - log.Infof("connected to dataSource %v@%v:%v/%v", p.Username, p.Host, p.Port, databaseName) } db := d.repository.SqlDB() // SetConnMaxLifetime sets the maximum amount of time a connection may be reused. @@ -119,3 +96,54 @@ func (d *dataSource) Close() error { func (d *dataSource) Repository() gorm.Repository { return d.repository } + +func (d *dataSource) Interval(p *Properties) error { + duration, err := time.ParseDuration(p.Interval) + if err != nil { + log.Errorf("dataSource parse duration failed: %v", err) + return err + } + time.Sleep(duration) + return nil +} + +func (d *dataSource) Connect(p *Properties) (err error) { + password := p.Password + if p.Config.Decrypt { + pwd, err := rsa.DecryptBase64([]byte(password), []byte(p.Config.DecryptKey)) + if err == nil { + password = string(pwd) + } + } + loc := strings.Replace(p.Loc, "/", "%2F", -1) + databaseName := strings.Replace(p.Database, "-", "_", -1) + parseTime := "False" + if p.ParseTime { + parseTime = "True" + } + source := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=%v&parseTime=%v&loc=%v", + p.Username, password, p.Host, p.Port, databaseName, p.Charset, parseTime, loc) + d.repository, err = gorm.Open(p.Type, source) + if err != nil { + log.Errorf("dataSource connection failed: %v (%v)", err, p) + if p.AutoReconnect { + // 重试间隔时间 + err := d.Interval(p) + if err != nil { + return err + } + if p.RetryTimes == -1 { + err = d.Connect(p) + } else if p.RetryTimes > p.NowRetryTimes { + p.NowRetryTimes++ + err = d.Connect(p) + } + + } else { + return err + } + } else { + log.Infof("connected to dataSource %v@%v:%v/%v", p.Username, p.Host, p.Port, databaseName) + } + return err +} \ No newline at end of file diff --git a/starter/gorm/datasource_test.go b/starter/gorm/datasource_test.go index 50244cf..abea5be 100644 --- a/starter/gorm/datasource_test.go +++ b/starter/gorm/datasource_test.go @@ -39,18 +39,22 @@ func init() { func TestDataSourceOpen(t *testing.T) { prop := &Properties{ - Type: "mysql", - Host: "mysql-dev", - Port: "3306", - Username: "test", - Password: "LcNxqoI4zZjAnpiTD7JQxLJR/IgL2iTiSZ2nd7KPEBgxMV+FVhPSzM+fgH93XqZJNpboN4F/buX22yLTXK38AcVGTfID3rmQAOAc9A2DIWNy5v9+3NOY00M8z4dR1XHojheK0681cY9QVjtlJ70jFFDXb7PjFc2fQ0GIyIjBQDY=", - Database: "test", - ParseTime: true, - Charset: "utf8", - Loc: "Asia/Shanghai", + Type: "mysql", + Host: "mysql-dev", + Port: "3306", + Username: "test", + Password: "LcNxqoI4zZjAnpiTD7JQxLJR/IgL2iTiSZ2nd7KPEBgxMV+FVhPSzM+fgH93XqZJNpboN4F/buX22yLTXK38AcVGTfID3rmQAOAc9A2DIWNy5v9+3NOY00M8z4dR1XHojheK0681cY9QVjtlJ70jFFDXb7PjFc2fQ0GIyIjBQDY=", + Database: "test", + ParseTime: true, + Charset: "utf8", + Loc: "Asia/Shanghai", + NowRetryTimes: 0, + RetryTimes: 2, + Interval: "1s", + AutoReconnect: true, Config: Config{ - Decrypt: true, - }, + Decrypt: true, + }, } dataSource := new(dataSource) diff --git a/starter/gorm/properties.go b/starter/gorm/properties.go index 16b1228..32119be 100644 --- a/starter/gorm/properties.go +++ b/starter/gorm/properties.go @@ -38,6 +38,10 @@ type Properties struct { Loc string `json:"loc" default:"Asia/Shanghai"` Config Config `json:"config"` ConnMaxLifetime string `json:"connMaxLifetime" default:"60s"` - MaxIdleConns int `json:"maxIdleConns" default:"20"` - MaxOpenConns int `json:"maxOpenConns" default:"200"` + MaxIdleConns int `json:"maxIdle_conns" default:"20"` + MaxOpenConns int `json:"maxOpen_conns" default:"200"` + AutoReconnect bool `json:"auto_reconnect" default:"true"` + RetryTimes int `json:"retry_times" default:"-1"` + Interval string `json:"interval" default:"3s"` + NowRetryTimes int `json:"now_retry_times" default:"0"` }