Skip to content

Allow editing a partition's range end - #602

Open
guodong-sq wants to merge 4 commits into
cashapp:masterfrom
guodong-sq:guodong/edit-partition-range-end
Open

guodong-sq wants to merge 4 commits into
cashapp:masterfrom
guodong-sq:guodong/edit-partition-range-end

Conversation

@guodong-sq

@guodong-sq guodong-sq commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

Why

A filtered backfill can spend hours scanning beyond the last matching record. Creation accepts one key range for all partitions, while each shard may need a different stopping point. Operators need to shorten an existing partition's range without moving its cursor.

What

Add an optional range-end edit to the partition form. Leave either edit field blank to preserve its current value.

How

The handler checks the snapshot for each field being changed. End-only edits preserve the cursor bytes, including binary cursors. It requires a paused partition with no outstanding runner lease and rejects edits to unbounded or non-UTF-8 ends. This excludes S3 partitions, whose client does not support custom ends.

An actual end change clears completed or partial precomputation so the next runner counts the new range. Historical processed counts remain intact; progress displays stop at 100%. Runners wait for counting to finish before marking a partition complete. Pause and cancellation still stop waiting runners. The existing cursor-only JVM signatures remain available, and the API dump includes the new endpoint signature.

Risk

This changes the persisted scope of an explicitly edited partition. Operators must use the client's key format and end-bound convention. Recounting the new range adds read load. The completion wait applies to all runs. Slow or failing count requests can delay completion or pause a run after processing ends. If a crashed runner leaves a lease behind, resume to recover the lease, then pause again before editing.

No database or wire-format migration is required.

Testing

No manual UI testing. Local database-backed validation used an isolated schema through BACKFILA_TEST_DATABASE=backfila_pr602_service_test to avoid an existing fixture-schema collision.

Generated with Codex

A partition's range end is fixed when the backfill is prepared. A run that
turns out to cover far more of the key space than it needs has no way to
stop early: the Edit Cursor form moves only the start cursor, and the range
on the creation screen is applied to every partition identically, so it
cannot express a per shard bound.

This is the common shape for a `filterCondition` that matches a narrow
slice of a large table. `computeOverallRange` derives the range from
`getUnfilteredBoundaryKeyValue`, which ignores the condition, so the run
walks every remaining key to the end of the table and emits empty batches
the whole way.

Add an optional `new_range_end` to the edit form and its handler. The
handler now requires a new cursor or a new range end rather than a new
cursor alone, and applies whichever is supplied.

Nothing else needs to change. `DbRunPartition.pkey_range_end` is already a
per partition column, and `BackfillRunner.loadMetaData` already reads it
per partition, so a narrowed end reaches the client on the next lease. Both
the runner and the precomputer stop when the client reports no batches past
the end, so neither can run past a lowered bound.

Copilot AI 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.

🟡 Changes recommended

Resolve concurrency races, invalidate stale precomputation state, and update the API dump.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds per-partition range-end editing to the paused backfill cursor workflow.

Changes:

  • Supports optional new_range_end updates.
  • Updates the edit form and button text.
  • Adds tests for range-end editing and concurrency behavior.
File summaries
File Reviewed changes
service/src/test/kotlin/app/cash/backfila/actions/EditPartitionCursorActionTest.kt Tests range-end updates and stale snapshots.
service/src/main/kotlin/app/cash/backfila/dashboard/EditPartitionCursorHandlerAction.kt Applies cursor and range-end changes; requires concurrency protection, precomputation invalidation, and API dump updates.
service/src/main/kotlin/app/cash/backfila/dashboard/EditPartitionCursorAction.kt Adds the range-end form field; unchanged values can overwrite concurrent edits.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread service/src/main/kotlin/app/cash/backfila/dashboard/EditPartitionCursorAction.kt Outdated
Validate both snapshots and require runners to release their leases before editing. Preserve untouched binary bounds, reject unbounded range edits, and reset counts only when the end changes. Cover paused-runner recovery and retain the cursor-only ABI.

Co-authored-by: OpenAI Codex <codex@openai.com>

Copilot AI 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.

Wait for persisted precomputation before completing a partition, while allowing pause and shutdown to cancel the wait. Cap the overall progress label at 100% and cover delayed counting and cancellation.

Co-authored-by: OpenAI Codex <codex@openai.com>

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Range-end-only edits incorrectly reject partitions with binary cursors.

Review effort: Lite
Findings: None

Resolved since last review (1)

Leave the new cursor field blank and validate its encoding and snapshot only when explicitly changing it. Preserve untouched cursor bytes during end-only updates and cover form submission, stale bounds, and atomic rejection of binary cursor changes.

Co-authored-by: OpenAI Codex <codex@openai.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.

2 participants