Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c6ee9ef
test: reproduce RPC idle disconnect during pending call
aron-cf Jul 1, 2026
5fc1224
fix: keep RPC connection busy while calls are pending
aron-cf Jul 1, 2026
f95c2d7
Surface container allocation failures as ContainerUnavailableError
aron-cf Jul 1, 2026
e6c77d3
Export ContainerUnavailableReason for typed error branching
aron-cf Jul 1, 2026
c4dbba5
Harden container-unavailable detection and error preference
aron-cf Jul 1, 2026
7df77da
Emit structured CONTAINER_UNAVAILABLE from containerFetch startup
aron-cf Jul 1, 2026
77f1f94
Start container explicitly before RPC WebSocket upgrade
aron-cf Jul 1, 2026
96e5df3
Only report OPERATION_INTERRUPTED for established sessions
aron-cf Jul 1, 2026
e33124f
Start container under a short budget with typed errors on the RPC path
aron-cf Jul 1, 2026
336e14f
Uppercase RPC in identifiers, prune redundant conversion, trim changeset
aron-cf Jul 1, 2026
d786e71
Surface never-connected teardown as retryable ContainerUnavailableError
aron-cf Jul 1, 2026
0b5a930
Make destroy() a no-op when the container was never admitted
aron-cf Jul 1, 2026
24a591b
Guard connect teardown, stamp causes, and trace the RPC path
aron-cf Jul 1, 2026
914f051
Namespace RPC spans under sandbox.rpc.* with sandbox identifiers
aron-cf Jul 1, 2026
b06bd08
Include operation in the sandbox.rpc.call span name
aron-cf Jul 1, 2026
3dd2ca3
Resolve sandbox trace identifiers lazily via a single callback
aron-cf Jul 1, 2026
3d0e938
Rank teardown causes as weak so the real failure wins
aron-cf Jul 1, 2026
cc3547a
Wrap the whole connect retry loop in one span
aron-cf Jul 1, 2026
e4bc0c8
Stamp wrapped cause chain on RPC error spans
aron-cf Jul 1, 2026
85f04a9
Clear stale connect-attempt cause on session establish
aron-cf Jul 2, 2026
07cd0f9
Consolidate platform admission-error matching into one helper
aron-cf Jul 2, 2026
f553148
Capture container exit code and stop reason on onStop disconnect cause
aron-cf Jul 6, 2026
ad9f343
Align RPC instance-get budget with platform 8s default
aron-cf Jul 6, 2026
66773f6
Harden RPC client callbacks and deferred-disconnect cleanup
aron-cf Jul 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/rpc-method-tracking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cloudflare/sandbox': patch
---

Keep RPC sessions alive while method calls are pending to avoid intermittent `RPC session was shut down by disposing the main stub` failures during concurrent sandbox startup.
5 changes: 5 additions & 0 deletions .changeset/surface-container-unavailable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cloudflare/sandbox': patch
---

Surface container capacity failures as retryable `ContainerUnavailableError` (with a `reason`) instead of masking them as `utils.createSession` interruptions or raw transport errors, make `destroy()` an idempotent no-op when the container was never admitted, and record the wrapped error `.cause` chain on RPC trace spans so the true startup failure (e.g. container not listening, network loss) is visible instead of the generic "no container instance" wrapper.
10 changes: 5 additions & 5 deletions packages/sandbox/src/bridge/warm-pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export interface PoolStats {
// Container RPC shapes (inherited by Sandbox from Container)
// ---------------------------------------------------------------------------

interface ContainerRpc {
interface ContainerRPC {
startAndWaitForPorts(): Promise<void>;
stop(signal?: string): Promise<void>;
renewActivityTimeout(): void;
Expand Down Expand Up @@ -205,7 +205,7 @@ export class WarmPool extends DurableObject<WarmPoolEnv> {
for (const containerUUID of [...this.warmContainers]) {
try {
const stub = this.getSandboxStub(containerUUID);
await (stub as unknown as ContainerRpc).stop();
await (stub as unknown as ContainerRPC).stop();
this.warmContainers.delete(containerUUID);
} catch (error) {
console.error({
Expand Down Expand Up @@ -296,7 +296,7 @@ export class WarmPool extends DurableObject<WarmPoolEnv> {

try {
const stub = this.getSandboxStub(containerUUID);
await (stub as unknown as ContainerRpc).startAndWaitForPorts();
await (stub as unknown as ContainerRPC).startAndWaitForPorts();
console.info({
message: 'Container started',
component: 'warm-pool',
Expand Down Expand Up @@ -364,7 +364,7 @@ export class WarmPool extends DurableObject<WarmPoolEnv> {
for (const containerUUID of this.warmContainers) {
try {
const stub = this.getSandboxStub(containerUUID);
(stub as unknown as ContainerRpc).renewActivityTimeout();
(stub as unknown as ContainerRPC).renewActivityTimeout();
} catch (error) {
console.error({
message: 'Failed to renew activity timeout',
Expand Down Expand Up @@ -455,7 +455,7 @@ export class WarmPool extends DurableObject<WarmPoolEnv> {
for (const uuid of toStop) {
try {
const stub = this.getSandboxStub(uuid);
await (stub as unknown as ContainerRpc).stop();
await (stub as unknown as ContainerRPC).stop();
stopped.push(uuid);
} catch (error) {
console.error({
Expand Down
Loading
Loading