Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
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 <noreply@anthropic.com>
  • Loading branch information
claude committed Oct 20, 2025
commit 0ecf5b7fc1a269ce7b5c576701a2e099e39b47de
11 changes: 6 additions & 5 deletions internal/cmd/vet.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"runtime/trace"
"slices"
"strings"
"sync"
"time"

_ "github.com/go-sql-driver/mysql"
Expand Down Expand Up @@ -386,6 +387,7 @@ type checker struct {
Stderr io.Writer
OnlyManagedDB bool
Client dbmanager.Client
clientOnce sync.Once
Replacer *shfmt.Replacer
}

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

if c.Client == nil {
// FIXME: Eventual race condition
client := dbmanager.NewClient(c.Conf.Servers)
c.Client = client
}
// Initialize the client exactly once, even if called concurrently
c.clientOnce.Do(func() {
c.Client = dbmanager.NewClient(c.Conf.Servers)
})

var ddl []string
files, err := sqlpath.Glob(s.Schema)
Expand Down
Loading