diff --git a/callbacks/query.go b/callbacks/query.go index 990bdce4..22965421 100644 --- a/callbacks/query.go +++ b/callbacks/query.go @@ -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 { diff --git a/gorm.go b/gorm.go index c3db1297..baa3a594 100644 --- a/gorm.go +++ b/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 } diff --git a/tests/easer_test.go b/tests/easer_test.go new file mode 100644 index 00000000..a1a7c607 --- /dev/null +++ b/tests/easer_test.go @@ -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") + } + }) +}