Skip to content

Commit 0ecf5b7

Browse files
committed
Fix race condition in database client initialization
Fixed a race condition in the checker's Client field initialization by using sync.Once to ensure thread-safe, single initialization even when fetchDatabaseUri is called concurrently. Changes: - Added sync.Once field (clientOnce) to checker struct - Replaced check-then-act pattern with sync.Once.Do() - Removed FIXME comment as issue is now resolved This ensures that even if multiple goroutines call fetchDatabaseUri simultaneously, the Client will only be initialized once without any race conditions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent d663cde commit 0ecf5b7

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

internal/cmd/vet.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"runtime/trace"
1515
"slices"
1616
"strings"
17+
"sync"
1718
"time"
1819

1920
_ "github.com/go-sql-driver/mysql"
@@ -386,6 +387,7 @@ type checker struct {
386387
Stderr io.Writer
387388
OnlyManagedDB bool
388389
Client dbmanager.Client
390+
clientOnce sync.Once
389391
Replacer *shfmt.Replacer
390392
}
391393

@@ -402,11 +404,10 @@ func (c *checker) fetchDatabaseUri(ctx context.Context, s config.SQL) (string, f
402404
return uri, cleanup, err
403405
}
404406

405-
if c.Client == nil {
406-
// FIXME: Eventual race condition
407-
client := dbmanager.NewClient(c.Conf.Servers)
408-
c.Client = client
409-
}
407+
// Initialize the client exactly once, even if called concurrently
408+
c.clientOnce.Do(func() {
409+
c.Client = dbmanager.NewClient(c.Conf.Servers)
410+
})
410411

411412
var ddl []string
412413
files, err := sqlpath.Glob(s.Schema)

0 commit comments

Comments
 (0)