Repository navigation
[db] add the activating client id column to sandboxes - #1066
Merged
the-gigi-pplx merged 1 commit intoOct 30, 2026
Merged
the-gigi-pplx merged 1 commit into
the-gigi-pplx merged 1 commit into
Conversation
the-gigi-pplx
marked this pull request as ready for review
October 28, 2026 22:49
the-gigi-pplx
marked this pull request as draft
October 29, 2026 20:32
Collaborator
Author
|
No longer on hold: the RFC in PR #1072 settles the table, and this pull request now adds |
the-gigi-pplx
marked this pull request as ready for review
October 30, 2026 06:58
the-gigi-pplx
force-pushed
the
gigi/pla-6985-add-activating-client-key-column-to-k8s-executions
branch
6 times, most recently
from
October 30, 2026 07:34
bf58b86 to
149f096
Compare
the-gigi-pplx
force-pushed
the
gigi/pla-6985-add-activating-client-key-column-to-k8s-executions
branch
from
October 30, 2026 07:38
149f096 to
9549682
Compare
kumarpallav-pplx
requested review from
NancyKwongPerplexity
and removed request for
shehan-pplx
October 30, 2026 15:36
NancyKwongPerplexity
approved these changes
Oct 30, 2026
the-gigi-pplx
deleted the
gigi/pla-6985-add-activating-client-key-column-to-k8s-executions
branch
October 30, 2026 17:30
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
Adds a nullable
activating_client_id textcolumn tosandboxes, recording which client created each sandbox's current runtime. Nothing reads or writes it yet. It's the record the per-client admission design in PR #1072 builds on, for both substrates.Terms
X-Client-IDwhen it's a valid, unreserved Kubernetes label value. Otherwise it'sunknown, and it'snativefor native/v1and admin calls. It's what the RFC in PR [docs] add RFCs for per-client admission independent of the substrate #1072 stores in records, pod labels and persisted operations ("Decision 2").nativefornative, the id when the key set names it, andunknownotherwise. Limits and metrics use keys, and records store ids.The problem
The per-client limits in PR #1072 have to know which client a sandbox's runtime belongs to, after the request that created it is gone:
X-Client-ID. These create a runtime with no request from the client that owns the sandbox:data_plane_sessions/service_route.rsandsession_route.rs) callPrepareIngressandQueueImplicitWaketo wake a sandbox at rest when traffic or a reattaching session reaches it. These are internal RPCs, so they carry no client header. On Kubernetes they create the pod throughensure_execution_ready_for_accessanddrive_prepared_wake.node_drain,restore_evacuated_sandbox) restores each resident sandbox onto another node, with no API request at all.Each of these is an inheriting activation. It still has to charge a client and label the pod it creates. An explicit ECW call is different, even when it comes from another client than the one that created the sandbox: its own header names the client, and the new runtime is attributed to that caller (RFC "Decision 1").
unknownwould move the sandbox out of its client's cap until that client activates it again itself. Warm-pool pods are the exception: they're created before any client exists, and a create that claims one has the header in hand.sandbox_k8s_executionswould leave Direct with nowhere to record the client.How this fixes it
sandboxes. One column,activating_client_id. On Kubernetes, pod tracking sets it from the tracked pod'sspace.pplx.net/client-idlabel. It means "the client whose activation created the current runtime". Both substrates can write it, and an inheriting activation reads it from the row it already loads. The writers ship separately (RFC "Decision 3"): row inserts, Kubernetes pod tracking, and Direct receipts.NULLmeans nothing is recorded, as for rows from before the column and sandboxes whose tracked pod was created without a label. Nothing filters on the column.CHECK.sandboxes_activating_client_id_checkallowsNULLor a non-empty Kubernetes label value: at most 63 characters, alphanumeric at both ends, with-,_and.allowed inside. The reserved ids (unknown,native,overflow) satisfy it. The format is a fixed rule, so it belongs in the schema, and a bad value fails at the write instead of later, when an inheriting activation copies it onto a pod label.CHECKNOT VALID. Adding it doesn't scansandboxes. Every existing row isNULL, and Postgres checks new writes either way. A later migration canVALIDATEit, but nothing depends on that.It ships on its own because a Postgres migration can't share a pull request with app code (
scripts/check-postgres-migrations-isolated.sh).sandbox_k8s_executionsis unchanged.Validation
check-migration-versions.sh,check-postgres-migrations-isolated.shandcheck-postgres-migrations-squawk.shpass. Squawk reports no issues.cargo nextest run -p pplx-space-db-migratepasses (54 tests, Postgres).space-db-migrator control-planeup,downandupagain from a fresh database. After eachup,sandboxes.activating_client_idis nullabletextwith no default,sandboxes_activating_client_id_checkexists withconvalidated = false, andsandbox_k8s_executionshas no new column.downremoves the column and the constraint, and leaves the previous migration as the latest applied version.pg_get_constraintdef), applied to a probe table:NULL,unknown,native,overflow,cleanup,batch-7,a,A.b_c-9, and a 63-character value;-lead,trail-,_x,x.,has space,a/b,éandNot A Label!.Not validated: a migration against a populated
sandboxestable under concurrent load.Dependencies
Rollout
ALTER TABLEneeds a briefACCESS EXCLUSIVElock on a busy table. While it waits behind a long transaction, othersandboxesqueries queue behind it. The one-secondlock_timeoutbounds each wait. At the default Job deadline, the migrator retries up to five attempts, about 20 seconds in the worst case. If every attempt loses, the migration Job fails and the deploy waits on it until a rerun succeeds.Severity and risk
Severity: does not apply. This is new schema with no readers.
Risk: low. Adding a nullable column with no default, and a
NOT VALIDCHECK, changes only the catalog, so it doesn't rewrite or scansandboxes. Postgres evaluates theCHECKon every insert and update of a row. For aNULLvalue that's aNULLtest, and otherwise a length check and a regular expression on at most 63 characters. Each lock wait is bounded by the one-secondlock_timeout, so queries queued behind it wait at most a second per attempt, or fail with55P03where the app roles set a shorterlock_timeout. A run that loses every attempt fails the migration Job and holds the deploy. Roll back by rolling back any image that reads or writes the column, then running the down migration, which drops it. Down runs once, without the lock retry up has, so rerun it if it times out. If the migration is reapplied, every sandbox startsNULL. A running Kubernetes sandbox whose pod carries a label gets the value back when pod tracking next sees the pod. Any other sandbox staysNULLuntil a caller's own activation writes it, because an inheriting activation keeps aNULLrecord.AI assistance: Claude Code drafted the migrations and this description.