refactor(saas): take two serialized apiserver round trips off the hosted create path#895
Conversation
A hosted create established its readiness watch only AFTER the Sandbox Create, which forced an authoritative Get right behind the watch to close the flip-before-watch window: one serialized apiserver round trip paid by every create, on a path production measures at ~140 ms of control plane against a 60-76 ms engine restore. The watch on the client-generated name now opens BEFORE the Create, so the create event itself arrives on the stream: the re-read disappears and the race window no longer exists rather than being patched over. Establish failure keeps the exact old behavior (create, then post-create watch or poll, failing open), and a stream that closes mid-wait still falls back to the ticker with the remaining deadline budget. watchReady keeps the post-create shape for waits whose object predates the watch (fork). TestWatchDrivenCreateNeedsNoSandboxGet pins the round-trip count the way the SDK pins its connection count, and TestReadyFlipDuringCreateWriteIsStillSeen pins the race the removed Get used to guard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Jannes Stubbemann <jannes@openclaw.rocks>
…the round trip The typo fast-fail pool pre-check (#646) pays an uncached SandboxPool Get on EVERY hosted create, serialized ahead of the Sandbox write. Hosted pools are pre-provisioned and stable, so the answer is the same on every request. A POSITIVE existence result is now cached per namespace/pool for 30s (poolCheckTTL); absence is NEVER cached, so a genuine typo still re-reads authoritatively and 404s instantly on every attempt. The pre-check is a UX guard, not a correctness gate: a pool deleted inside the window falls through to the controller's bounded grace (#637), exactly the path a direct (non-gateway) create always took. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Jannes Stubbemann <jannes@openclaw.rocks>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughSandbox creation now caches positive pool checks for 30 seconds and establishes readiness watches before creating sandboxes. Readiness waiting falls back to polling when needed, with tests covering cache behavior and watch-driven readiness. ChangesSandbox create flow
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant CreateFlow
participant KubernetesWatch
participant KubernetesAPI
Client->>CreateFlow: sandbox.create
CreateFlow->>KubernetesAPI: Check SandboxPool
CreateFlow->>KubernetesWatch: establishSandboxWatch
CreateFlow->>KubernetesAPI: Create Sandbox
KubernetesAPI-->>KubernetesWatch: Sandbox readiness event
KubernetesWatch-->>CreateFlow: Terminal readiness outcome
CreateFlow-->>Client: Forward response
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/saas/controlplane/poolcheck_test.go`:
- Around line 53-124: Add a regression test alongside
TestRepeatCreateSkipsThePoolPreCheckRoundTrip that creates the same pool name in
two different namespaces or organizations, verifies each namespace performs its
own positive pre-check, and confirms the cache entry from the first namespace is
not reused by the second. Reuse existing helpers such as poolGetCountingClient
and createOnce, and assert the total SandboxPool Get count reflects two isolated
cache keys.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: afe09c5e-7050-44e7-8985-a42eb134548e
📒 Files selected for processing (5)
internal/saas/controlplane/controlplane.gointernal/saas/controlplane/forward.gointernal/saas/controlplane/poolcheck_test.gointernal/saas/controlplane/readywatch.gointernal/saas/controlplane/readywatch_test.go
A positive cache entry for one org's namespace must never satisfy the pre-check for the same pool name in another org's namespace. The key already carries the namespace; this pins it as a regression test, per review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Jannes Stubbemann <jannes@openclaw.rocks>
Thinking Path
Linked Issues or Issue Description
Related: #871 (the TTI gap tracking issue names control-plane cost as the remaining lever). The reservation-protocol follow-up for the remaining serialized write is filed as #893.
What Changed
Verification
Risks
Model Used
Checklist
🤖 Generated with Claude Code
Summary by CodeRabbit