Skip to content

Test that a replica keeps a row written after an expiring row in the same transaction - #1410

Draft
DavidCockerill wants to merge 4 commits into
mainfrom
david/1399-replica-expiresat-cluster-test
Draft

DavidCockerill wants to merge 4 commits into
mainfrom
david/1399-replica-expiresat-cluster-test

Conversation

@DavidCockerill

@DavidCockerill DavidCockerill commented Nov 13, 2026 •

Copy link
Copy Markdown
Member
A duck scientist and a caveman check two fridges: the milk is gone from both, the pickles stayed in both, as a replica keeps a row after another row expires

📝 Summary

Adds a two-node test for HarperFast/harper#4391. That fix stops a replica from using an earlier row's expiry in the same transaction (HarperFast/harper#4390). The wrong expiry made the replica hide the row while the origin kept it. This PR also bumps core to that fix, so the test runs against it.

Closes #1399

🔧 Changes

✅ Verification

  • replicatedWriteOwnExpiry.test.mjs, with its fixture (schema, two one-transaction resources, config): one request writes Exp (expiration: 5) and then Plain in one transaction, another the reverse. Once Exp expires on B, B still has both Plain rows. With core at main's pin, B loses the row written after Exp; with this core it passes in every run.
  • Gates: typecheck, lint:required and format pass. test:unit has 3 failures, all identical with core at main's pin (/proc and the /var symlink on macOS). The new test, addNodeTableExpiration and cacheReplicationSource pass together locally; CI runs the full cluster and non-cluster tiers.
  • Performance: the bumped core change runs on every replicated write. A write with no expiry in its options or context reads what it read before; only one that would take the context's expiry reads one more property. No allocation, lock or await, so no benchmark (harper#4391).
  • After review: the expiry wait now also requires the Exp rows on B first, and a read error counts as neither 0 nor 1 (the final round's finding), not re-reviewed.
  • PR QA: skipped @ b87c394 — not substantive: a test and a core bump whose behavior change is harper#4391's

🤖 Generated by Claude Code (Anthropic Claude Opus); posted via @DavidCockerill.

Release target: v5.4 — ships with harper#4391's fix, milestoned v5.4

Depends-on: HarperFast/harper#4391

Related PRs: #1395 independent (the core sync this branch builds on)
Complexity: easy

Deferred findings

  • 20189ba273efa47b minor performance — core — No Performance statement for per-write expiry selection on replication apply path brought in by core bump — NOT FILED
  • 7d37570d95d95fb8 nit data-integrity — core — Fix might split an origin transaction into per-event replica transactions, breaking crash atomicity — NOT FILED

Review-Coverage: authored=claude; ran=gemini,codex,gemini-carbon; late=gemini-carbon:adjudicated; adjudicated=domain; declined=cursor-grok,cursor-composer,muse; rounds=2; full=2 @ b87c394

Review-Attention: skim ~2m (decisions: cluster-test-vs-unit-only) @ b87c394

DavidCockerill and others added 4 commits November 13, 2026 18:11
…same transaction

Two nodes; one request writes Exp (table expiration 5 s) and then Plain in one
transaction, another the reverse. After Exp expires on B, B still has both
Plain rows. Fails with core before HarperFast/harper#4391, where the replica
gave Plain the Exp row's expiry and hid it.

Refs #1399

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A source-applied write takes only its own expiry (HarperFast/harper#4390).
Re-point to the merge commit once that PR lands.

Refs #1399

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #1399

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… read errors distinct

A per-record error read as 0 could pass for an expired row and end the expiry
wait before any expiry. Also check the origin's row written before Exp.

Refs #1399

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

Cluster test: a replica keeps a row written after an expiring row in the same transaction

1 participant