Skip to content

Commit

Permalink
acquire writelock when updating DSN
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-garcia committed Aug 16, 2023
1 parent 4a93acb commit 81d3012
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 4 deletions.
10 changes: 6 additions & 4 deletions dsnexec/pkg/dsnexec/dsnexec.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,17 @@ func (w *Handler) Exec() error {

// UpdateDSN updates the dsn for a source.
func (w *Handler) UpdateDSN(path, content string) error {
w.l.RLock()
defer w.l.RUnlock()

// update the local state
// acquire a write lock and update the config
w.l.Lock()
w.config.Sources[path] = DBConnInfo{
Driver: w.config.Sources[path].Driver,
DSN: content,
}
w.l.Unlock()

// acquire a read lock and execute
w.l.RLock()
defer w.l.RUnlock()
if err := w.exec(); err != nil {
return fmt.Errorf("failed initial execute: %v", err)
}
Expand Down
44 changes: 44 additions & 0 deletions dsnexec/pkg/dsnexec/dsnexec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,55 @@ import (
"database/sql/driver"
"fmt"
"reflect"
"sync"
"testing"

"github.com/google/uuid"
"github.com/infobloxopen/db-controller/dsnexec/pkg/tdb"
)

func TestHandler_UpdateDSN_Concurrency(t *testing.T) {
w := &Handler{
config: Config{
Sources: map[string]DBConnInfo{
"test": {
Driver: "postgres",
DSN: "postgres://user:pass@localhost:5432/dbname?sslmode=disable",
},
},
Commands: []Command{
{
Command: "select 1",
},
},
},
}

// setup the destination DSN to use the test driver
w.config.Destination = DBConnInfo{
Driver: "nulldb",
DSN: fmt.Sprintf("nulldb://%s", t.Name()),
}

// launch 100 goroutines to update the DSN concurrently
c := make(chan struct{})
wg := sync.WaitGroup{}
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
<-c
for j := 0; j < 100; j++ {
dsn := fmt.Sprintf("postgres://user:%s@localhost:5432/dbname?sslmode=disable", uuid.New())
w.UpdateDSN("test", dsn)
}
wg.Done()
}()
}
// launch the goroutines
close(c)
wg.Wait()
}

func TestHandler_UpdateDSN(t *testing.T) {
type fields struct {
config Config
Expand Down
23 changes: 23 additions & 0 deletions dsnexec/pkg/dsnexec/nulldb/nulldb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package nulldb

import (
"database/sql"
"database/sql/driver"
"fmt"
)

var (
defaultDriver *d
)

type d struct {
}

func init() {
defaultDriver = &d{}
sql.Register("nulldb", defaultDriver)
}

func (d *d) Open(name string) (driver.Conn, error) {
return nil, fmt.Errorf("unsupported Open in nulldb")
}

0 comments on commit 81d3012

Please sign in to comment.