Repository navigation
sandbox-store: move the publish path's stopped, activity, absent-delete and rollback writes - #1333
Merged
ac-pplx merged 1 commit intoNov 3, 2026
Conversation
|
Thanks for opening this pull request! A SPACE maintainer will take a look. CONTRIBUTING.md explains how we review outside contributions. |
ac-pplx
force-pushed
the
ac/lifecycle-move-internal-api
branch
from
November 2, 2026 21:04
3505eb3 to
71a927d
Compare
ac-pplx
force-pushed
the
ac/lifecycle-move-internal-api
branch
from
November 2, 2026 23:25
71a927d to
9f272b7
Compare
This was referenced Nov 3, 2026
ac-pplx
marked this pull request as ready for review
November 3, 2026 03:51
ac-pplx
marked this pull request as draft
November 3, 2026 03:52
ac-pplx
force-pushed
the
ac/lifecycle-move-internal-api
branch
from
November 3, 2026 06:00
9f272b7 to
973fc96
Compare
ac-pplx
marked this pull request as ready for review
November 3, 2026 06:29
kumarpallav-pplx
requested review from
kumarpallav-pplx and
nikhilbirmiwal-pplx
November 3, 2026 06:30
nikhilbirmiwal-pplx
approved these changes
Nov 3, 2026
…te and rollback writes PublishNodeState still wrote the `sandboxes` row inline in four places in the internal API: the stopped convergence, the activity-clock advance, the delete of stopped Direct rows a node reports absent, and the activation-rollback convergence. Move each statement, byte for byte apart from its binds, into pplx-space-sandbox-store: - published_state::converge_stopped_sandboxes (statement) -> ingest::converge_published_stopped - published_state::update_activity_timestamps (statement) -> ingest::advance_published_activity - published_state::DELETE_ABSENT_STOPPED_SANDBOXES -> ingest::delete_published_absent_stopped - sandbox_quarantine_store::apply_activation_rollback_candidates (sandboxes update) -> quarantine::converge_activation_rollback The callers keep the publication transaction, its candidate locks, the recordset serialization and their error mapping. The statements' sql! locators now name the store modules. Neither file has a sandbox_writes baseline entry left.
ac-pplx
force-pushed
the
ac/lifecycle-move-internal-api
branch
from
November 3, 2026 21:24
973fc96 to
042daad
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PublishNodeStatewrote thesandboxesrow inline in four internal-API places. Each statement moves intopplx-space-sandbox-storewith its SQL text byte-for-byte; only the binds change. Each new function's doc names the fact it writes and any unusual guards. Callers keep the publication transaction, candidate locks (FOR UPDATE), recordset serialization and error mapping.published_state::converge_stopped_sandboxes(statement) →ingest::converge_published_stopped(observed projection; has no evacuation exemption)published_state::update_activity_timestamps(statement) →ingest::advance_published_activity(observed projection; checks onlyactive_node_id)published_state::DELETE_ABSENT_STOPPED_SANDBOXES→ingest::delete_published_absent_stopped(inference; itsFOR UPDATE OF sstays inside the statement)sandbox_quarantine_store::apply_activation_rollback_candidates(UPDATE sandboxes) → newquarantine::converge_activation_rollback(observed projection). It returnsbool, where the caller previously checkedrows_affected() != 1;idis the primary key, so the two are equivalent.architecture-baseline.toml: both files'pattern_ratchet.sandbox_writesentries are removed (3 and 1). Thefile_sizecap forpublished_state.rsdrops from 3658 to 3504; the old cap was already stale at 3632. The internal-apiAGENTS.mdnow points the stopped projection atpplx_space_sandbox_store::ingest. No test files change (git diff --stat $(git merge-base origin/main HEAD) HEAD -- '*test*' '*/tests/*'is empty).sql!locators change: these four statements now reportpplx_space_sandbox_store::ingest/::quarantineinpg_stat_activityand query monitoring, instead of the internal-api modules.Validation
cargo nextest run -p pplx-space-sandbox-store -p pplx-space-internal-api-server -p pplx-space-internal-api-svc: 431 passed, 0 skipped. Postgres ran in a container.cargo nextest run -p pplx-space-api -p pplx-space-template-mgr: 1865 passed, 1 failed, 1 skipped (an opt-in#[ignore]benchmark). The failure,routes::e2b::tests::detail_reports_authoritative_federated_ownership_not_metadata, is a JSON key-order snapshot mismatch. Under this package selection it fails the same way onorigin/main, and it passes in CI's full workspace test run.cargo clippy -p pplx-space-sandbox-store -p pplx-space-internal-api-server --all-targets -- -D warnings: clean.cargo arch, plus--base-baseline/--base-architecturefrommain: 0 required findings.'started'from the stopped convergence failsnode_publication_converges_only_from_its_source_lifecycles.s.lifecycle = 'stopped'from the absent delete failsabsent_report_deletes_only_a_stopped_direct_rowandabsent_stopped_delete_decides_on_the_row_committed_while_it_waits.publish_sandbox_state_updates_activity_clocks_without_touching_updated_at.placement_changed_atin the rollback failsactivation_rollback_receipts_converge_stable_targets_with_attempt_fence.install-fc-vendor.sh,up.sh): up in 628 s.scripts/tests/smoke-kind-typed.sh all: ECW 85 passed, 0 failed, 3 inconclusive; native 35 passed, 0 failed; wall 3126 s.ecw.cold_create_environmentandecw.warm_pool_environmentpassed on rerun onceSPACE_SMOKE_KIND_COLD_RECEIPTSand a token file were set.local.restarted_btrfs_send_is_rejected_and_retriedneeds otel telemetry and was not run.Severity and risk
Severity: does not apply (refactor). Risk is low: same SQL text and binds, same transaction. Roll back by reverting the commit.
Rollout
No migration. Old and new pods issue identical statements; only the locator comment differs.
Open PRs that will need to rebase
converge_stopped_sandboxesstatement:crates/libs/internal/api/server/src/published_state.rs→crates/libs/sandbox/store/src/ingest.rs(converge_published_stopped). [cluster-controller] re-place an evacuated stopped sandbox as stopped on another node, materialized by the shim without a VM #826 also exempts arestoringrow marked for a stopped re-placement, so its rebase has to update that function's doc sentence "it does not exempt a row marked for the node-drain redrive" as well.Not covered
active_node_id = $2guard has no test: weakening it fails nothing. The candidate selection already requiress.active_node_id = $1underFOR UPDATEin the same transaction, so no test through the publication can observe it.AI assistance: Claude Code (an AI agent) wrote the code change, ran the validation and drafted this description.
After the wave-2 restack
This PR is one layer of a 10-PR stack, restacked onto main
c5fdf0c7(which includes #826) and then rebased mechanically onto42a99002, which changed only baseline context lines, in order #1329 → #1336 → #1338 → #1339 → #1342 → #1347 → #1333 → #1335 → #1328 → #1332. The validation earlier in this description ran at pre-restack heads; this layer's head is042daad2.restoring/stoppedexclusion toconverge_stopped_sandboxes. It is carried intoingest::converge_published_stopped, byte-identical to main's statement, and the store doc now describes it. For every file [cluster-controller] re-place an evacuated stopped sandbox as stopped on another node, materialized by the shim without a VM #826 and this stack share, each SQL line [cluster-controller] re-place an evacuated stopped sandbox as stopped on another node, materialized by the shim without a VM #826 added was checked to be present verbatim at the top head, in place or in the store module it moved to.cargo fmt --all -- --check,cargo check --workspace --all-targets --all-featuresandcargo arch(0 required findings, with main's layers and table-owner rules), and the ratchet and caps this layer changes are recounted exactly.e90aa284before that rebase; nextest passed 4370 tests again at77fbae1e):cargo clippy --workspace --locked --all-targets --all-features -- -D warningsis clean, andSPACE_CI_REQUIRE_TEST_DEPS=1 cargo nextest run --all-featurespassed 4355 tests across the store, api, internal-api server, cluster-controller server, metrics, db-test-fixtures, common-core, common-svc and portability crates, [cluster-controller] re-place an evacuated stopped sandbox as stopped on another node, materialized by the shim without a VM #826's suites included.scripts/tests/smoke-kind-typed.sh allgave ECW 91/91 and native 42/42, including [cluster-controller] re-place an evacuated stopped sandbox as stopped on another node, materialized by the shim without a VM #826'snative.forced_drain_re_places_stopped_sandboxand its re-drain and restarted variants. The Direct substrate lane'sallgave ECW 51/51 and native 27/27. No flakes and no reruns.+/-lines and its SQL string literals match its reviewed head (range-diff plus a literal multiset compare).