fix memory leaks in PrepareStatementDB

This commit is contained in:
Zehui Chen 2024-08-07 11:51:33 +08:00
parent 4a50b36f63
commit 408ec66048

View File

@ -17,18 +17,16 @@ type Stmt struct {
} }
type PreparedStmtDB struct { type PreparedStmtDB struct {
Stmts map[string]*Stmt Stmts map[string]*Stmt
PreparedSQL []string Mux *sync.RWMutex
Mux *sync.RWMutex
ConnPool ConnPool
} }
func NewPreparedStmtDB(connPool ConnPool) *PreparedStmtDB { func NewPreparedStmtDB(connPool ConnPool) *PreparedStmtDB {
return &PreparedStmtDB{ return &PreparedStmtDB{
ConnPool: connPool, ConnPool: connPool,
Stmts: make(map[string]*Stmt), Stmts: make(map[string]*Stmt),
Mux: &sync.RWMutex{}, Mux: &sync.RWMutex{},
PreparedSQL: make([]string, 0, 100),
} }
} }
@ -48,12 +46,18 @@ func (db *PreparedStmtDB) Close() {
db.Mux.Lock() db.Mux.Lock()
defer db.Mux.Unlock() defer db.Mux.Unlock()
for _, query := range db.PreparedSQL { for _, stmt := range db.Stmts {
if stmt, ok := db.Stmts[query]; ok { go func(s *Stmt) {
delete(db.Stmts, query) // make sure the stmt must finish preparation first
go stmt.Close() <-s.prepared
} if s.Stmt != nil {
_ = s.Close()
}
}(stmt)
} }
// I think setting it to nil should be better, as there should be no one
// writing into it after calling Close, but leave it for compatibility and safety
db.Stmts = make(map[string]*Stmt)
} }
func (sdb *PreparedStmtDB) Reset() { func (sdb *PreparedStmtDB) Reset() {
@ -63,7 +67,6 @@ func (sdb *PreparedStmtDB) Reset() {
for _, stmt := range sdb.Stmts { for _, stmt := range sdb.Stmts {
go stmt.Close() go stmt.Close()
} }
sdb.PreparedSQL = make([]string, 0, 100)
sdb.Stmts = make(map[string]*Stmt) sdb.Stmts = make(map[string]*Stmt)
} }
@ -118,7 +121,6 @@ func (db *PreparedStmtDB) prepare(ctx context.Context, conn ConnPool, isTransact
db.Mux.Lock() db.Mux.Lock()
cacheStmt.Stmt = stmt cacheStmt.Stmt = stmt
db.PreparedSQL = append(db.PreparedSQL, query)
db.Mux.Unlock() db.Mux.Unlock()
return cacheStmt, nil return cacheStmt, nil