reuse connections to DB (#76)

This commit is contained in:
Dominic Wong
2021-03-24 10:22:48 +00:00
committed by GitHub
parent d68fdeb516
commit 40738bedc8
4 changed files with 49 additions and 32 deletions

View File

@@ -2,15 +2,18 @@ package handler
import (
"context"
"database/sql"
"fmt"
"regexp"
"strings"
"sync"
"time"
"github.com/micro/micro/v3/service/auth"
"github.com/micro/micro/v3/service/errors"
pb "github.com/micro/services/users/proto"
"golang.org/x/crypto/bcrypt"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/schema"
)
@@ -63,13 +66,14 @@ type Token struct {
}
type Users struct {
Time func() time.Time
Dialector gorm.Dialector
dbMigrations map[string]bool
sync.RWMutex
Time func() time.Time
dbConn *sql.DB
gormConns map[string]*gorm.DB
}
func NewHandler(t func() time.Time, d gorm.Dialector) *Users {
return &Users{Time: t, Dialector: d, dbMigrations: map[string]bool{}}
func NewHandler(t func() time.Time, dbConn *sql.DB) *Users {
return &Users{Time: t, dbConn: dbConn, gormConns: map[string]*gorm.DB{}}
}
func (u *Users) getDBConn(ctx context.Context) (*gorm.DB, error) {
@@ -77,23 +81,36 @@ func (u *Users) getDBConn(ctx context.Context) (*gorm.DB, error) {
if !ok {
return nil, fmt.Errorf("missing account from context")
}
db, err := gorm.Open(u.Dialector, &gorm.Config{
NamingStrategy: schema.NamingStrategy{
TablePrefix: fmt.Sprintf("%s_", strings.ReplaceAll(acc.Issuer, "-", "")),
},
})
u.RLock()
if conn, ok := u.gormConns[acc.Issuer]; ok {
u.RUnlock()
return conn, nil
}
u.RUnlock()
u.Lock()
// double check
if conn, ok := u.gormConns[acc.Issuer]; ok {
u.Unlock()
return conn, nil
}
defer u.Unlock()
db, err := gorm.Open(
postgres.New(postgres.Config{
Conn: u.dbConn,
}),
&gorm.Config{
NamingStrategy: schema.NamingStrategy{
TablePrefix: fmt.Sprintf("%s_", strings.ReplaceAll(acc.Issuer, "-", "")),
},
})
if err != nil {
return nil, err
}
// skip migration if we've already done it
if u.dbMigrations[acc.Issuer] {
return db, nil
}
if err := db.AutoMigrate(&User{}, &Token{}); err != nil {
return nil, err
}
// record success
u.dbMigrations[acc.Issuer] = true
u.gormConns[acc.Issuer] = db
return db, nil
}