Fix bd-yvlc: in-memory database deadlock in migrations

- Force single connection for all in-memory databases (including file::memory:)
- Close rows before executing statements in external_ref migration
- Prevents connection pool deadlock with MaxOpenConns(1)
- Fixes test failures in syncbranch_test.go
This commit is contained in:
Steve Yegge
2025-11-15 12:42:02 -08:00
parent bd6dca507d
commit 944ed1033d
3 changed files with 14 additions and 5 deletions

View File

@@ -11,7 +11,6 @@ func MigrateExternalRefColumn(db *sql.DB) error {
if err != nil {
return fmt.Errorf("failed to check schema: %w", err)
}
defer func() { _ = rows.Close() }()
for rows.Next() {
var cid int
@@ -20,6 +19,7 @@ func MigrateExternalRefColumn(db *sql.DB) error {
var dflt *string
err := rows.Scan(&cid, &name, &typ, &notnull, &dflt, &pk)
if err != nil {
rows.Close()
return fmt.Errorf("failed to scan column info: %w", err)
}
if name == "external_ref" {
@@ -29,9 +29,13 @@ func MigrateExternalRefColumn(db *sql.DB) error {
}
if err := rows.Err(); err != nil {
rows.Close()
return fmt.Errorf("error reading column info: %w", err)
}
// Close rows before executing any statements to avoid deadlock with MaxOpenConns(1)
rows.Close()
if !columnExists {
_, err := db.Exec(`ALTER TABLE issues ADD COLUMN external_ref TEXT`)
if err != nil {

View File

@@ -56,11 +56,14 @@ func New(path string) (*SQLiteStorage, error) {
return nil, fmt.Errorf("failed to open database: %w", err)
}
// For :memory: databases, force single connection to ensure cache sharing works properly.
// SQLite's shared cache mode for in-memory databases only works reliably with one connection.
// Without this, different connections in the pool can't see each other's writes (bd-b121).
if path == ":memory:" {
// For all in-memory databases (including file::memory:), force single connection.
// SQLite's in-memory databases are isolated per connection by default.
// Without this, different connections in the pool can't see each other's writes (bd-b121, bd-yvlc).
isInMemory := path == ":memory:" ||
(strings.HasPrefix(path, "file:") && strings.Contains(path, "mode=memory"))
if isInMemory {
db.SetMaxOpenConns(1)
db.SetMaxIdleConns(1)
}
// Test connection