feat: use XORM EngineGroup instead of single Engine connection (#7212)

Resolves #7207

Add new configuration to make XORM work with a main and replicas database instances. The follow configuration parameters were added:

- `HOST_PRIMARY`
- `HOST_REPLICAS`
- `LOAD_BALANCE_POLICY`. Options:
    - `"WeightRandom"` -> `xorm.WeightRandomPolicy`
    - `"WeightRoundRobin`  -> `WeightRoundRobinPolicy`
    - `"LeastCon"` -> `LeastConnPolicy`
    - `"RoundRobin"` -> `xorm.RoundRobinPolicy()`
    - default: `xorm.RandomPolicy()`
- `LOAD_BALANCE_WEIGHTS`

Co-authored-by: pat-s <patrick.schratz@gmail.com@>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7212
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: pat-s <patrick.schratz@gmail.com>
Co-committed-by: pat-s <patrick.schratz@gmail.com>
This commit is contained in:
pat-s 2025-03-30 11:34:02 +00:00 committed by Gusted
parent a23d0453a3
commit 63a80bf2b9
19 changed files with 463 additions and 129 deletions

View file

@ -22,11 +22,11 @@ import (
var fixturesLoader *testfixtures.Loader
// GetXORMEngine gets the XORM engine
func GetXORMEngine(engine ...*xorm.Engine) (x *xorm.Engine) {
func GetXORMEngine(engine ...*xorm.Engine) (x *xorm.Engine, err error) {
if len(engine) == 1 {
return engine[0]
return engine[0], nil
}
return db.DefaultContext.(*db.Context).Engine().(*xorm.Engine)
return db.GetMasterEngine(db.DefaultContext.(*db.Context).Engine())
}
func OverrideFixtures(opts FixturesOptions, engine ...*xorm.Engine) func() {
@ -41,7 +41,10 @@ func OverrideFixtures(opts FixturesOptions, engine ...*xorm.Engine) func() {
// InitFixtures initialize test fixtures for a test database
func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) {
e := GetXORMEngine(engine...)
e, err := GetXORMEngine(engine...)
if err != nil {
return err
}
var fixtureOptionFiles func(*testfixtures.Loader) error
if opts.Dir != "" {
fixtureOptionFiles = testfixtures.Directory(opts.Dir)
@ -93,10 +96,12 @@ func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) {
// LoadFixtures load fixtures for a test database
func LoadFixtures(engine ...*xorm.Engine) error {
e := GetXORMEngine(engine...)
var err error
e, err := GetXORMEngine(engine...)
if err != nil {
return err
}
// (doubt) database transaction conflicts could occur and result in ROLLBACK? just try for a few times.
for i := 0; i < 5; i++ {
for range 5 {
if err = fixturesLoader.Load(); err == nil {
break
}