Implemented easer feature to reduce the DB load
This commit is contained in:
parent
970341a12a
commit
a688acb023
@ -9,7 +9,6 @@ import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Query(db *gorm.DB) {
|
||||
@ -17,7 +16,6 @@ func Query(db *gorm.DB) {
|
||||
BuildQuerySQL(db)
|
||||
|
||||
var _query = func(db *gorm.DB) {
|
||||
time.Sleep(5 * time.Second)
|
||||
if !db.DryRun && db.Error == nil {
|
||||
rows, err := db.Statement.ConnPool.QueryContext(db.Statement.Context, db.Statement.SQL.String(), db.Statement.Vars...)
|
||||
if err != nil {
|
||||
|
12
gorm.go
12
gorm.go
@ -57,11 +57,11 @@ type Config struct {
|
||||
// Plugins registered plugins
|
||||
Plugins map[string]Plugin
|
||||
// Ease database load by grouping identical queries
|
||||
Ease bool
|
||||
Ease bool
|
||||
EaseQueue *sync.Map
|
||||
|
||||
callbacks *callbacks
|
||||
cacheStore *sync.Map
|
||||
easeQueue *sync.Map
|
||||
}
|
||||
|
||||
// Apply update config to new config
|
||||
@ -170,8 +170,8 @@ func Open(dialector Dialector, opts ...Option) (db *DB, err error) {
|
||||
config.cacheStore = &sync.Map{}
|
||||
}
|
||||
|
||||
if config.Ease && config.easeQueue == nil {
|
||||
config.easeQueue = &sync.Map{}
|
||||
if config.Ease && config.EaseQueue == nil {
|
||||
config.EaseQueue = &sync.Map{}
|
||||
}
|
||||
|
||||
db = &DB{Config: config, clone: 1}
|
||||
@ -501,13 +501,13 @@ func (db *DB) Ease(cb func(*DB)) *DB {
|
||||
}
|
||||
eq.wg.Add(1)
|
||||
|
||||
var runner, ok = db.easeQueue.LoadOrStore(hash, eq)
|
||||
var runner, ok = db.EaseQueue.LoadOrStore(hash, eq)
|
||||
et := runner.(*easedTask)
|
||||
|
||||
if !ok {
|
||||
cb(db)
|
||||
et.wg.Done()
|
||||
db.easeQueue.Delete(hash)
|
||||
db.EaseQueue.Delete(hash)
|
||||
return db
|
||||
}
|
||||
|
||||
|
75
tests/easer_test.go
Normal file
75
tests/easer_test.go
Normal file
@ -0,0 +1,75 @@
|
||||
package tests_test
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestEaser(t *testing.T) {
|
||||
t.Run("once", func(t *testing.T) {
|
||||
db1 := DB.Unscoped()
|
||||
db1.Config.EaseQueue = &sync.Map{}
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
|
||||
incr := 0
|
||||
|
||||
testQuery := func(d *gorm.DB) {
|
||||
time.Sleep(time.Second)
|
||||
incr++
|
||||
}
|
||||
|
||||
go func() {
|
||||
db1.Ease(testQuery)
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
db1.Ease(testQuery)
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
if incr != 1 {
|
||||
t.Error("easer had to run the query only once")
|
||||
}
|
||||
})
|
||||
t.Run("twice", func(t *testing.T) {
|
||||
db1 := DB.Unscoped()
|
||||
db1.Config.EaseQueue = &sync.Map{}
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
|
||||
incr := 0
|
||||
|
||||
testQuery := func(d *gorm.DB) {
|
||||
time.Sleep(time.Second)
|
||||
incr++
|
||||
}
|
||||
|
||||
go func() {
|
||||
db1.Statement.SQL.WriteString("q1")
|
||||
db1.Ease(testQuery)
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
db1.Statement.SQL.WriteString("q2")
|
||||
db1.Ease(testQuery)
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
if incr != 2 {
|
||||
t.Error("easer had to run two separate queries")
|
||||
}
|
||||
})
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user