Skip to content

Commit 77ae363

Browse files
committed
Fix SQLite database locking issues with concurrent access
Configure SQLite connections with proper concurrency handling to prevent "database is locked" errors when multiple operations access the database simultaneously. Changes: - Add busy_timeout (5s) to wait for locks instead of failing immediately - Enable WAL mode for better concurrent read/write performance - Configure connection pool to serialize writes (SQLite best practice) Fixes session store and memory database SQLite implementations.
1 parent f697a9a commit 77ae363

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

pkg/memory/database/sqlite/sqlite.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,20 @@ type MemoryDatabase struct {
1414
}
1515

1616
func NewMemoryDatabase(path string) (database.Database, error) {
17-
db, err := sql.Open("sqlite", path)
17+
// Add query parameters for better concurrency handling
18+
// _busy_timeout: Wait up to 5 seconds if database is locked
19+
// _journal_mode=WAL: Enable Write-Ahead Logging for better concurrent access
20+
db, err := sql.Open("sqlite", path+"?_busy_timeout=5000&_journal_mode=WAL")
1821
if err != nil {
1922
return nil, err
2023
}
2124

25+
// Configure connection pool to serialize writes (SQLite limitation)
26+
// This prevents "database is locked" errors from concurrent writes
27+
db.SetMaxOpenConns(1)
28+
db.SetMaxIdleConns(1)
29+
db.SetConnMaxLifetime(0)
30+
2231
_, err = db.ExecContext(context.Background(), "CREATE TABLE IF NOT EXISTS memories (id TEXT PRIMARY KEY, created_at TEXT, memory TEXT)")
2332
if err != nil {
2433
return nil, err

pkg/session/store.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,20 @@ type SQLiteSessionStore struct {
4242

4343
// NewSQLiteSessionStore creates a new SQLite session store
4444
func NewSQLiteSessionStore(path string) (Store, error) {
45-
db, err := sql.Open("sqlite", path)
45+
// Add query parameters for better concurrency handling
46+
// _busy_timeout: Wait up to 5 seconds if database is locked
47+
// _journal_mode=WAL: Enable Write-Ahead Logging for better concurrent access
48+
db, err := sql.Open("sqlite", path+"?_busy_timeout=5000&_journal_mode=WAL")
4649
if err != nil {
4750
return nil, err
4851
}
4952

53+
// Configure connection pool to serialize writes (SQLite limitation)
54+
// This prevents "database is locked" errors from concurrent writes
55+
db.SetMaxOpenConns(1)
56+
db.SetMaxIdleConns(1)
57+
db.SetConnMaxLifetime(0)
58+
5059
_, err = db.ExecContext(context.Background(), `
5160
CREATE TABLE IF NOT EXISTS sessions (
5261
id TEXT PRIMARY KEY,

0 commit comments

Comments
 (0)