From 6c61a57cfc24d344529685977855341ae9f17239 Mon Sep 17 00:00:00 2001 From: Daniel Theophanes Date: Mon, 29 Oct 2018 09:09:21 -0700 Subject: database/sql: add SetConnMaxIdleTime Allow removing a connection from the connection pool after it has been idle for a period of time, without regard to the total lifespan of the connection. Fixes #25232 Change-Id: Icff157b906769a2d2d45c67525e04a72feb8d832 Reviewed-on: https://go-review.googlesource.com/c/go/+/145758 Run-TryBot: Daniel Theophanes TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/database/sql/sql_test.go | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'src/database/sql/sql_test.go') diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go index 6f59260cda..a1437c46c9 100644 --- a/src/database/sql/sql_test.go +++ b/src/database/sql/sql_test.go @@ -3593,6 +3593,61 @@ func TestStatsMaxIdleClosedTen(t *testing.T) { } } +func TestMaxIdleTime(t *testing.T) { + list := []struct { + wantMaxIdleTime time.Duration + wantIdleClosed int64 + timeOffset time.Duration + }{ + {time.Nanosecond, 1, 10 * time.Millisecond}, + {time.Hour, 0, 10 * time.Millisecond}, + } + baseTime := time.Unix(0, 0) + defer func() { + nowFunc = time.Now + }() + for _, item := range list { + nowFunc = func() time.Time { + return baseTime + } + t.Run(fmt.Sprintf("%v", item.wantMaxIdleTime), func(t *testing.T) { + db := newTestDB(t, "people") + defer closeDB(t, db) + + db.SetMaxOpenConns(1) + db.SetMaxIdleConns(1) + db.SetConnMaxIdleTime(item.wantMaxIdleTime) + db.SetConnMaxLifetime(0) + + preMaxIdleClosed := db.Stats().MaxIdleTimeClosed + + if err := db.Ping(); err != nil { + t.Fatal(err) + } + + nowFunc = func() time.Time { + return baseTime.Add(item.timeOffset) + } + + db.mu.Lock() + closing := db.connectionCleanerRunLocked() + db.mu.Unlock() + for _, c := range closing { + c.Close() + } + if g, w := int64(len(closing)), item.wantIdleClosed; g != w { + t.Errorf("got: %d; want %d closed conns", g, w) + } + + st := db.Stats() + maxIdleClosed := st.MaxIdleTimeClosed - preMaxIdleClosed + if g, w := maxIdleClosed, item.wantIdleClosed; g != w { + t.Errorf(" got: %d; want %d max idle closed conns", g, w) + } + }) + } +} + type nvcDriver struct { fakeDriver skipNamedValueCheck bool -- cgit v1.3