Skip to content

Fix SQLite concurrency and queue visibility - #315

Merged
mira-2026 merged 9 commits into
mainfrom
mira/sqlite-worker-concurrency
Jul 23, 2026
Merged

Fix SQLite concurrency and queue visibility#315
mira-2026 merged 9 commits into
mainfrom
mira/sqlite-worker-concurrency

Conversation

@mira-2026

@mira-2026 mira-2026 commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • make SQLite WAL mode part of database initialization and use immediate write transactions where web/worker contention can otherwise cause lock-upgrade failures
  • refresh the Execution queue every 5 seconds, invalidate it immediately after UI-triggered jobs, and retain recent completions so short jobs remain visible
  • add the Execution queue to the main Dashboard above Actions, with Queue and Actions sharing the column height beside Backups
  • move the active chat model into a badge and simplify the context line

Why

PR #314 split the web and worker execution planes. The production rollout exposed one transient database is locked failure while both processes wrote to SQLite. The Jobs queue also polled every 15 seconds while idle and only rendered active executions, so short jobs could complete without ever appearing.

Verification

All local checks ran inside CPU/memory-limited systemd scopes:

  • backend/test/openClawChatSnapshotStore.test.ts: 13 passed
  • src/test/chatHeader.test.tsx: 2 passed
  • targeted Execution queue component test: 1 passed
  • targeted scheduled-job hook/invalidation test: 1 passed
  • targeted main-page rendering test: 1 passed
  • targeted chat-page header regression test: 1 passed
  • ESLint on all 21 touched files: passed
  • git diff --check: passed

Full build, typecheck, lint, and test coverage are delegated to GitHub CI to avoid resource contention on the production VPS.

Production rollout note

The live database was backed up and migrated to WAL before this PR. Both split services are active with zero restarts, queue capacity is 1/1, and a post-migration manual worker job completed successfully without a lock error. The backup is:

/home/ubuntu/.local/state/mira-dashboard-rollbacks/task-367-20260723T1407CEST/mira-dashboard.pre-wal.db

@mira-2026
mira-2026 requested a review from rajohan as a code owner July 23, 2026 12:46
@mira-2026 mira-2026 added priority: high High-priority work for the next active cycle status: needs-review Ready for human or agent review type: bugfix Fixes broken or incorrect behavior area: chat Chat UI, streaming, messages, attachments, or voice UX area: database Database dashboard, Postgres, PgBouncer, or query views area: ops Operational actions, deploys, services, backups, and health area: frontend Frontend UI, client state, routing, and browser behavior area: backend Backend API, server routes, services, and integrations labels Jul 23, 2026
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@mira-2026, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 38 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 759f17ca-6ab6-4619-91d5-2933c22ef8b8

📥 Commits

Reviewing files that changed from the base of the PR and between ad2d1e4 and 866927b.

📒 Files selected for processing (4)
  • backend/src/routes/cacheRoutes.ts
  • backend/test/serviceBehavior.test.ts
  • src/pages/Dashboard.tsx
  • src/test/pageBehavior.test.tsx
📝 Walkthrough

Walkthrough

SQLite initialization now requires WAL and write transactions acquire immediate locks. Cache refreshes support scheduled-job execution, process spawning preserves selected systemd user-bus variables, and the dashboard updates execution history, cache invalidation, and chat metadata display.

Changes

SQLite concurrency behavior

Layer / File(s) Summary
Enable WAL and immediate write locks
backend/src/database.ts, backend/src/chat/..., backend/src/services/...
WAL is validated during initialization, and SQLite write transactions use immediate locking.
Validate WAL concurrency
backend/test/openClawChatSnapshotStore.test.ts
Tests cover WAL activation failures and concurrent snapshot writes.
Document WAL-safe database operations
docs/architecture/database.md, docs/operations/runbooks.md, docs/setup/production-deploy.md
Documentation uses online backups and describes WAL sidecars and integrity checks.

Job execution dashboard flow

Layer / File(s) Summary
Refresh execution data after mutations
src/hooks/*.ts
Execution polling and mutation handlers now invalidate execution and scheduled-job queries.
Render active and recent executions
src/components/features/..., src/pages/Dashboard.tsx
The dashboard displays recent executions beside service actions with configurable card layout.
Validate execution refresh and history
src/test/*.test.tsx
Tests verify query invalidation and cancelled execution history.

Cache refresh execution flow

Layer / File(s) Summary
Route cache refreshes through scheduled jobs
backend/src/routes/cacheRoutes.ts, backend/src/services/cacheRefresh.ts
Cache refreshes choose scheduled manual execution or immediate job enqueueing based on the cache key.
Validate cache refresh mappings
backend/test/serviceBehavior.test.ts
Tests verify mappings, manual runs, and unmapped refreshes.

Scoped process environments

Layer / File(s) Summary
Scope systemd-run child environments
backend/src/lib/jobResources.ts, backend/src/lib/processes.ts
systemd-run processes preserve selected user-bus environment variables while excluding unrelated inherited values.
Test environment scoping
backend/test/jobExecutionQueue.test.ts
Tests cover restricted, inherited, full-path, and omitted environment inputs.

Chat header metadata

Layer / File(s) Summary
Display and validate header metadata
src/components/features/chat/ChatHeader.tsx, src/test/*Header.test.tsx, src/test/pageBehavior.test.tsx
The header displays model metadata separately from revised context status text, with updated assertions.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested labels: type: performance, type: tests, area: database, area: ops

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: fixing SQLite concurrency and queue visibility.
Description check ✅ Passed The description is concrete and covers summary, motivation, verification, and rollout notes, though several template sections are omitted.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.67841% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
backend/src/routes/cacheRoutes.ts 95.71% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
backend/src/database.ts (1)

451-456: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Verify the WAL switch actually succeeded.

PRAGMA journal_mode = WAL is run via .run() and its result is discarded. If WAL can't be enabled for some reason (unsupported filesystem, read-only mount, etc.), SQLite silently falls back to a different journal mode with no error and no log — quietly defeating the entire point of this PR (avoiding lock-upgrade failures). The test suite already checks this via database.query("PRAGMA journal_mode").get(); consider doing the same here and logging/throwing if the mode isn't wal.

🛡️ Proposed fix to verify WAL mode
-    initializedDatabase.run("PRAGMA journal_mode = WAL");
+    const journalMode = initializedDatabase
+        .query("PRAGMA journal_mode = WAL")
+        .get() as { journal_mode: string } | undefined;
+    if (journalMode?.journal_mode !== "wal") {
+        console.warn(
+            `Expected WAL journal mode, got "${journalMode?.journal_mode}" for ${databasePath}`
+        );
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/src/database.ts` around lines 451 - 456, Verify the journal mode
after the PRAGMA in the database initialization flow: query the result of
“PRAGMA journal_mode” and confirm it is “wal” case-insensitively. If WAL was not
enabled, log the failure or throw an initialization error before calling
runSchemaSql, preserving the existing successful initialization path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@backend/src/database.ts`:
- Around line 451-456: Verify the journal mode after the PRAGMA in the database
initialization flow: query the result of “PRAGMA journal_mode” and confirm it is
“wal” case-insensitively. If WAL was not enabled, log the failure or throw an
initialization error before calling runSchemaSql, preserving the existing
successful initialization path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 20d64548-8a49-4674-a675-ab7833bf09f1

📥 Commits

Reviewing files that changed from the base of the PR and between 89c3dfb and fc538f6.

📒 Files selected for processing (20)
  • backend/src/chat/openClawChatSnapshotStore.ts
  • backend/src/database.ts
  • backend/src/services/backups.ts
  • backend/src/services/cacheRefresh.ts
  • backend/src/services/dockerUpdater.ts
  • backend/src/services/gitHygiene.ts
  • backend/src/services/logRotation.ts
  • backend/test/openClawChatSnapshotStore.test.ts
  • src/components/features/chat/ChatHeader.tsx
  • src/components/features/dashboard/ServiceActionsCard.tsx
  • src/components/features/jobs/JobExecutionQueueCard.tsx
  • src/hooks/useBackups.ts
  • src/hooks/useCache.ts
  • src/hooks/useJobExecutions.ts
  • src/hooks/useOpsActions.ts
  • src/hooks/useScheduledJobs.ts
  • src/pages/Dashboard.tsx
  • src/test/chatHeader.test.tsx
  • src/test/componentBehavior.test.tsx
  • src/test/frontendBehavior.test.tsx
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
  • GitHub Check: Analyze JavaScript and TypeScript
  • GitHub Check: backend-checks
  • GitHub Check: frontend-checks
🔇 Additional comments (19)
src/hooks/useJobExecutions.ts (1)

52-60: LGTM!

Also applies to: 73-76

src/hooks/useBackups.ts (1)

5-5: LGTM!

Also applies to: 71-71, 92-92, 112-112, 133-133

src/hooks/useCache.ts (1)

4-4: LGTM!

Also applies to: 152-152

src/hooks/useOpsActions.ts (1)

1-4: LGTM!

Also applies to: 109-119

src/hooks/useScheduledJobs.ts (1)

5-5: LGTM!

Also applies to: 185-185

src/components/features/jobs/JobExecutionQueueCard.tsx (1)

8-8: LGTM!

Also applies to: 26-56, 183-223

src/components/features/dashboard/ServiceActionsCard.tsx (1)

17-22: LGTM!

Also applies to: 158-158

src/pages/Dashboard.tsx (1)

33-33: LGTM!

Also applies to: 317-320

src/test/componentBehavior.test.tsx (1)

3264-3265: LGTM!

src/test/frontendBehavior.test.tsx (1)

132-132: LGTM!

Also applies to: 2076-2092

src/components/features/chat/ChatHeader.tsx (1)

6-7: LGTM!

Also applies to: 53-56, 93-95

src/test/chatHeader.test.tsx (1)

60-64: LGTM!

backend/src/chat/openClawChatSnapshotStore.ts (1)

523-535: LGTM!

Also applies to: 537-548, 661-692, 694-703

backend/src/services/backups.ts (1)

1095-1095: LGTM!

backend/src/services/cacheRefresh.ts (1)

2383-2383: LGTM!

backend/src/services/dockerUpdater.ts (1)

2069-2069: LGTM!

Also applies to: 2806-2806

backend/src/services/gitHygiene.ts (1)

510-510: LGTM!

backend/src/services/logRotation.ts (1)

1987-1987: LGTM!

backend/test/openClawChatSnapshotStore.test.ts (1)

31-87: LGTM!

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fc538f6ea9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread backend/src/database.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/src/database.ts`:
- Around line 445-463: Update enableRequiredWalJournalMode to catch errors from
the PRAGMA journal_mode query, close databaseConnection on a best-effort basis,
and rethrow the original error. Preserve the existing journal-mode validation
and connection-closing behavior when the query succeeds but does not return
“wal”.

In `@docs/architecture/database.md`:
- Around line 104-105: The destructive reset commands in
docs/architecture/database.md lines 104-105 and docs/operations/runbooks.md
lines 62-63 must fail closed: add the same set -euo pipefail guard and
five-second SQLite busy timeout before the DELETE statements in both locations,
ensuring deletion cannot proceed after backup, permission, or integrity-check
failure.
- Around line 67-72: Resolve db_path from the service environment’s
MIRA_DASHBOARD_DB_PATH before each SQLite backup instead of hardcoding the
default path. Apply this to docs/architecture/database.md lines 67-72 and
99-103, and docs/operations/runbooks.md lines 57-61; keep each existing backup,
permission, and validation flow unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2b7856a3-ec8a-429e-a455-28e96f9a26d7

📥 Commits

Reviewing files that changed from the base of the PR and between fc538f6 and ac0c9db.

📒 Files selected for processing (16)
  • backend/src/database.ts
  • backend/src/lib/jobResources.ts
  • backend/src/lib/processes.ts
  • backend/src/routes/cacheRoutes.ts
  • backend/src/services/cacheRefresh.ts
  • backend/test/jobExecutionQueue.test.ts
  • backend/test/openClawChatSnapshotStore.test.ts
  • backend/test/serviceBehavior.test.ts
  • docs/architecture/database.md
  • docs/operations/runbooks.md
  • docs/setup/production-deploy.md
  • src/hooks/useBackups.ts
  • src/hooks/useCache.ts
  • src/pages/Dashboard.tsx
  • src/test/frontendBehavior.test.tsx
  • src/test/pageBehavior.test.tsx
💤 Files with no reviewable changes (1)
  • src/pages/Dashboard.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/hooks/useCache.ts
  • backend/test/openClawChatSnapshotStore.test.ts
  • src/hooks/useBackups.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (4)
  • GitHub Check: CodeQL
  • GitHub Check: Analyze JavaScript and TypeScript
  • GitHub Check: backend-checks
  • GitHub Check: frontend-checks
🔇 Additional comments (20)
src/test/pageBehavior.test.tsx (1)

2999-3001: LGTM!

backend/src/routes/cacheRoutes.ts (3)

11-23: LGTM!


263-291: LGTM!


351-354: LGTM!

backend/test/serviceBehavior.test.ts (3)

821-824: LGTM!


863-882: LGTM!


909-934: LGTM!

backend/src/lib/jobResources.ts (2)

101-124: LGTM!


141-142: LGTM!

backend/src/lib/processes.ts (2)

1-1: LGTM!


66-66: LGTM!

backend/test/jobExecutionQueue.test.ts (2)

6-6: LGTM!


176-214: LGTM!

backend/src/database.ts (1)

473-473: LGTM!

backend/src/services/cacheRefresh.ts (1)

2273-2279: LGTM!

Also applies to: 2391-2391

docs/architecture/database.md (2)

25-26: LGTM!

Also applies to: 28-34


74-76: LGTM!

docs/setup/production-deploy.md (2)

156-172: LGTM!


196-196: LGTM!

src/test/frontendBehavior.test.tsx (1)

132-132: LGTM!

Also applies to: 155-155, 2077-2093, 2102-2115, 2479-2485, 3544-3557

Comment thread backend/src/database.ts
Comment thread docs/architecture/database.md Outdated
Comment thread docs/architecture/database.md Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ac0c9db49b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread backend/src/routes/cacheRoutes.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2decc0f6b7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread docs/setup/production-deploy.md Outdated
Comment thread backend/src/routes/cacheRoutes.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 99f1296c00

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread backend/src/routes/cacheRoutes.ts Outdated
Comment thread backend/src/services/cacheRefresh.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ad2d1e4899

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/pages/Dashboard.tsx
Comment thread backend/src/routes/cacheRoutes.ts Outdated
@mira-2026
mira-2026 merged commit 47e5024 into main Jul 23, 2026
5 checks passed
@mira-2026
mira-2026 deleted the mira/sqlite-worker-concurrency branch July 23, 2026 15:41
mira-2026 added a commit that referenced this pull request Jul 23, 2026
## Summary

- refresh the active Execution queue query as soon as Dashboard cache,
backup, scheduled-job/log-rotation, and ops-action requests are
dispatched
- add one short follow-up refresh while a long request is still pending,
then retain the existing completion refresh
- show only the effective chat speed in the header badge, such as
`Standard` instead of `Default (Standard)`
- add the missing Active class icon and use the shared centered empty
state in the Execution queue card

## Verification

- `bun test` — 394 passed, 0 failed
- `bun run lint`
- `bun run build`
- `bun run format:check`
- `git diff --check`

## Context

Focused frontend follow-up to #315 and Mira Dashboard task #367. No API
changes, dependencies, or new UI/state patterns.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: backend Backend API, server routes, services, and integrations area: chat Chat UI, streaming, messages, attachments, or voice UX area: database Database dashboard, Postgres, PgBouncer, or query views area: frontend Frontend UI, client state, routing, and browser behavior area: ops Operational actions, deploys, services, backups, and health priority: high High-priority work for the next active cycle status: needs-review Ready for human or agent review type: bugfix Fixes broken or incorrect behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants