forked from mystiq/dex
Merge pull request #330 from ericchiang/mem_db_concurrent_conns
db: only allow one open connection for in memory databases
This commit is contained in:
commit
4855805983
2 changed files with 47 additions and 1 deletions
|
@ -67,7 +67,14 @@ func NewConnection(cfg Config) (*gorp.DbMap, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// NOTE(ericchiang): sqlite does NOT work with SetMaxIdleConns.
|
if u.Host == ":memory:" {
|
||||||
|
// NOTE(ericchiang): sqlite3 coordinates concurrent clients through file locks.
|
||||||
|
// In memory databases do not support concurrent calls. Limit the number of
|
||||||
|
// open connections to 1.
|
||||||
|
//
|
||||||
|
// See: https://www.sqlite.org/faq.html#q5
|
||||||
|
db.SetMaxOpenConns(1)
|
||||||
|
}
|
||||||
dialect = gorp.SqliteDialect{}
|
dialect = gorp.SqliteDialect{}
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("unrecognized database driver")
|
return nil, errors.New("unrecognized database driver")
|
||||||
|
|
39
db/conn_test.go
Normal file
39
db/conn_test.go
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/coreos/dex/connector"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestConcurrentSqliteConns tests concurrent writes to a single in memory database.
|
||||||
|
func TestConcurrentSqliteConns(t *testing.T) {
|
||||||
|
dbMap := NewMemDB()
|
||||||
|
repo := NewConnectorConfigRepo(dbMap)
|
||||||
|
|
||||||
|
var (
|
||||||
|
once sync.Once
|
||||||
|
wg sync.WaitGroup
|
||||||
|
)
|
||||||
|
|
||||||
|
n := 1000
|
||||||
|
wg.Add(n)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
go func() {
|
||||||
|
configs := []connector.ConnectorConfig{
|
||||||
|
&connector.LocalConnectorConfig{ID: "local"},
|
||||||
|
}
|
||||||
|
// Setting connector configs both deletes and writes to a single table
|
||||||
|
// within a transaction.
|
||||||
|
if err := repo.Set(configs); err != nil {
|
||||||
|
// Don't print 1000 errors, only the first.
|
||||||
|
once.Do(func() {
|
||||||
|
t.Errorf("concurrent connections to sqlite3: %v", err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
Loading…
Reference in a new issue