Skip to content

improvement(tables): read row counts and versions through an append-only change log - #8653

Merged
TheodoreSpeaks merged 5 commits into
stagingfrom
fix/table-version-lock
Oct 6, 2026
Merged

TheodoreSpeaks merged 5 commits into
stagingfrom
fix/table-version-lock

Conversation

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator

Summary

  • Every row write updates row_count / rows_version on the table's single user_table_definitions row and holds that lock until its commit is acknowledged by a standby, so one slow commit makes every other writer to the same table hit lock_timeout and roll back
  • Phase 1 of moving those counters to an append-only change log (the buffered-counter pattern): adds user_table_row_changes, and every reader now reads stored value + unfolded tail in one statement (lib/table/row-changes.ts) — table get/list/query counts, the snapshot cache key, and the snapshot mount-safety check
  • rows_version is the stored version plus the count of log rows, never max(id) — ids are allocated before commit, so a late commit can carry a lower id than one already seen and the cache would serve stale bytes
  • New /api/cron/fold-table-row-changes (every minute, helm + docker crontab) folds each table's log into its definition row in one statement; SKIP LOCKED so it never waits on a held row and overlapping sweeps skip each other. updated_at now moves at fold time, so it trails the last insert/delete by up to a minute
  • Fork copy no longer overwrites row_count after copying rows — the trigger already counts them, and once writers log changes the overwrite would double-count
  • No behavior change on its own: nothing writes to the log yet. Phase 2 (separate PR, after this deploys) points the row-count / rows_version triggers at the log; shipping both together would let old instances read the stored column alone mid-deploy
  • Prod schedules crons in infra; that entry is a separate infra PR

Type of Change

  • Improvement

Testing

  • New lib/table/row-changes.integration.ts against real Postgres (push + migrate): reads include the tail, fold keeps stored + tail constant, fold skips a held definition row in <1s instead of waiting, version stays exact and non-decreasing with 8 concurrent appenders while folds run, sweep covers every table. Reverting the reads to the stored column turns the read tests red
  • Table integration suites on a migrated DB (155 passed), secret-provenance.integration.ts fixture gains the log table
  • Local E2E on the running app: logged changes by hand → tables page showed stored + tail; cron fold → stored values updated, page unchanged, log empty, updated_at in UTC
  • bun run test (local-only failures are .env-driven rate-limit/timeout tests untouched here, plus one flaky sandbox test that passes alone), bun run lint, check:audits, check:migrations origin/staging, block-registry check, docs-manifest:check, drizzle generate clean

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing (new tests pass the test-audit authoring gate)
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

🤖 Generated with Claude Code

https://claude.ai/code/session_01YVFtF6hWSD8ot7omjmqF5U

@vercel

vercel Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
docs Ready Ready Preview Oct 6, 2026 2:53am UTC

Request Review

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 16 files

Fix all with cubic | Re-trigger cubic

Comment thread apps/sim/lib/table/row-changes.integration.ts Outdated
@greptile-apps

greptile-apps Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Critical risk] Adds database schema and background job for table row tracking.

The PR appears safe to merge based on the changes reviewed.

Summary

This PR adds an append-only table row-change log, reads live counts and versions as stored values plus the unfolded log, and schedules a background fold. It also removes a redundant row-count overwrite during fork copying.

  • The three previous findings are resolved and do not remain outstanding.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Table definition: stored count and version] --> C[Live reads: stored values plus log tail]
  B[Append-only row-change log] --> C
  B --> D[Scheduled fold]
  D --> A
  D --> E[Delete folded log rows]
Loading

Reviews (4) · Last reviewed commit: "chore(db): format regenerated row-change..."

Comment thread apps/sim/lib/table/row-changes.ts
Comment thread apps/sim/lib/table/row-changes.ts Outdated
@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@TheodoreSpeaks I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot 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.

No issues found across 17 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

Comment thread apps/sim/app/api/cron/fold-table-row-changes/route.ts Outdated
@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@TheodoreSpeaks I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot 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.

No issues found across 18 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@TheodoreSpeaks
TheodoreSpeaks force-pushed the fix/table-version-lock branch from fe3c623 to 5197510 Compare October 6, 2026 02:51
@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@TheodoreSpeaks I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot 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.

No issues found across 18 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@TheodoreSpeaks
TheodoreSpeaks merged commit 239526a into staging Oct 6, 2026
38 checks passed
@TheodoreSpeaks
TheodoreSpeaks deleted the fix/table-version-lock branch October 6, 2026 03:37

This branch was successfully deployed

1 active deployment
Preview — 51975103 Deployed Oct 6, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant