Skip to content

Fix WAL mode set and sqlite connection pool setup for cursorcli#221

Open
bago2k4 wants to merge 2 commits into
devfrom
cursorcli-db-fixes
Open

Fix WAL mode set and sqlite connection pool setup for cursorcli#221
bago2k4 wants to merge 2 commits into
devfrom
cursorcli-db-fixes

Conversation

@bago2k4

@bago2k4 bago2k4 commented May 21, 2026

Copy link
Copy Markdown
Contributor

This pull request improves how SQLite databases are accessed and managed in the Cursor CLI provider, with a focus on connection pooling and ensuring reliable use of WAL (Write-Ahead Logging) mode. The changes prevent file descriptor leaks, ensure consistent file modification detection, and centralize the logic for enabling WAL mode.

Database connection management improvements:

  • Limited SQLite connection pools to a single open and idle connection, and set a connection max lifetime to prevent file descriptor accumulation in both sqlite_reader.go and watcher.go. [1] [2] [3] [4]

WAL mode handling enhancements:

  • Removed per-connection enabling of WAL mode, and instead introduced a new EnsureWALMode function in sqlite_reader.go that ensures the database is in WAL mode by opening a brief read-write connection. This function is now called once per session when a session is first seen in the watcher. [1] [2] [3]

These changes make database access safer and more reliable, especially under heavy usage or when monitoring many sessions.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts how the Cursor CLI provider opens SQLite databases to (1) reduce the chance of accumulating file descriptors via database/sql connection pooling, and (2) centralize enabling SQLite WAL mode into a one-time helper invoked when a session is first detected.

Changes:

  • Constrain SQLite connection pools to 1 open / 1 idle connection and set a max lifetime for read-only DB handles used by the watcher and session reader.
  • Remove per-read PRAGMA journal_mode=WAL calls and introduce EnsureWALMode(dbPath) to set/verify WAL mode via a brief read-write connection.
  • Call EnsureWALMode once when a session is first observed by the watcher.

3 most important improvements to make:

  1. Update EnsureWALMode to open SQLite using a safer/consistent DSN (e.g., file: + filepath.ToSlash(...)) and mode=rw to avoid accidentally creating new DB files and to align with the repo’s established SQLite DSN pattern (see specstory-cli/pkg/provenance/store.go:29).
  2. Narrow the CursorWatcher mutex scope in hasSessionChanged so the lock only protects map state, not the DB I/O and WAL initialization work.
  3. Add a focused unit test for EnsureWALMode (this package already has tests) that creates a temp SQLite DB, checks PRAGMA journal_mode, runs EnsureWALMode, and asserts the mode becomes WAL.

Unit test opportunities (high-signal only):

  • A single test covering EnsureWALMode’s journal-mode transition and error behavior (especially if switching to mode=rw) would meaningfully reduce risk without adding tautological coverage.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
specstory-cli/pkg/providers/cursorcli/watcher.go Uses a controlled read-only pool for polling counts and ensures WAL once when a session is first seen.
specstory-cli/pkg/providers/cursorcli/sqlite_reader.go Applies controlled pooling for reads and adds centralized WAL-mode enforcement via EnsureWALMode.

Comment thread specstory-cli/pkg/providers/cursorcli/watcher.go Outdated
Comment on lines 225 to +228
// Always check record count - don't rely on file modification time
// SQLite with WAL mode may not update file mtime when records are added

// Open database to count records (with WAL mode)
// Open database to count records (read-only with controlled pool)
Comment thread specstory-cli/pkg/providers/cursorcli/sqlite_reader.go
Comment on lines +357 to +362
// EnsureWALMode ensures the database is running in WAL journal mode.
// WAL mode is required so that the -wal file exists and file modification
// detection works reliably. This opens a brief read-write connection and
// is intended to be called once per session database, not on every read.
func EnsureWALMode(dbPath string) error {
db, err := sql.Open("sqlite", dbPath)
return fmt.Errorf("failed to enable WAL mode: got %q instead", newMode)
}

slog.Info("Enabled WAL mode on database", "path", dbPath)
Comment on lines +357 to +361
// EnsureWALMode ensures the database is running in WAL journal mode.
// WAL mode is required so that the -wal file exists and file modification
// detection works reliably. This opens a brief read-write connection and
// is intended to be called once per session database, not on every read.
func EnsureWALMode(dbPath string) error {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants