Skip to content

Commit feafd32

Browse files
Fix session reuse to reuse existing healthy session (#86)
* Fix session reuse Reuse existing healthy session instead of recreating them, preventing "Control process initialization timeout" when the same session ID is requested concurrently. * Add changeset * Modify basic example to request new sandboxes
1 parent e943505 commit feafd32

File tree

9 files changed

+154
-851
lines changed

9 files changed

+154
-851
lines changed

.changeset/curly-eyes-tell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cloudflare/sandbox": patch
3+
---
4+
5+
Fix session reuse to reuse existing healthy session

examples/basic/app/index.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,26 @@ interface ListFilesResponse {
3636
timestamp: string;
3737
}
3838

39+
// Generate or retrieve a stable sandbox ID for this browser tab
40+
function getClientSandboxId(): string {
41+
const storageKey = 'sandbox-client-id';
42+
43+
// Try to get existing ID from sessionStorage (persists across page reloads)
44+
let sandboxId = sessionStorage.getItem(storageKey);
45+
46+
if (!sandboxId) {
47+
// Generate new ID for this tab
48+
sandboxId = `client-${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
49+
sessionStorage.setItem(storageKey, sandboxId);
50+
}
51+
52+
return sandboxId;
53+
}
54+
3955
// Simple API client to replace direct HttpClient usage
4056
class SandboxApiClient {
4157
private baseUrl: string;
58+
private sandboxId: string;
4259
private onCommandComplete?: (
4360
success: boolean,
4461
exitCode: number,
@@ -64,6 +81,7 @@ class SandboxApiClient {
6481
} = {}
6582
) {
6683
this.baseUrl = options.baseUrl || window.location.origin;
84+
this.sandboxId = getClientSandboxId();
6785
this.onCommandComplete = options.onCommandComplete;
6886
this.onCommandStart = options.onCommandStart;
6987
this.onError = options.onError;
@@ -73,6 +91,7 @@ class SandboxApiClient {
7391
const response = await fetch(`${this.baseUrl}${url}`, {
7492
headers: {
7593
"Content-Type": "application/json",
94+
"X-Sandbox-Client-Id": this.sandboxId,
7695
...options.headers,
7796
},
7897
...options,

examples/basic/src/index.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,16 @@ type Env = {
4141
};
4242

4343
// Helper to get sandbox instance with user-specific ID
44-
function getUserSandbox(env: Env) {
45-
// For demo purposes, use a fixed sandbox ID. In production, you might extract from:
44+
function getUserSandbox(env: Env, request: Request) {
45+
// Get client-provided sandbox ID from header (persists across page reloads, unique per tab)
46+
const clientSandboxId = request.headers.get("X-Sandbox-Client-Id");
47+
48+
// Use client ID if provided, otherwise generate one
49+
// In production, you would also use:
4650
// - Authentication headers
4751
// - URL parameters
4852
// - Session cookies
49-
const sandboxId = "demo-user-sandbox";
53+
const sandboxId = clientSandboxId || `sandbox-${Date.now()}-${generateSecureRandomString()}`;
5054
return getSandbox(env.Sandbox, sandboxId);
5155
}
5256

@@ -66,7 +70,7 @@ export default {
6670
const pathname = url.pathname;
6771

6872
try {
69-
const sandbox = getUserSandbox(env) as unknown as Sandbox<unknown>;
73+
const sandbox = getUserSandbox(env, request) as unknown as Sandbox<unknown>;
7074

7175
// Notebook API endpoints
7276
if (pathname === "/api/notebook/session" && request.method === "POST") {

examples/basic/wrangler.jsonc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"class_name": "Sandbox",
1818
"image": "./Dockerfile",
1919
"name": "sandbox",
20-
"max_instances": 1
20+
"max_instances": 5,
21+
"instance_type": "standard-2"
2122
}
2223
],
2324
"durable_objects": {

examples/code-interpreter/package.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,7 @@
1212
},
1313
"author": "",
1414
"license": "MIT",
15-
"devDependencies": {
16-
"typescript": "^5.5.2",
17-
"wrangler": "^4.27.0"
18-
},
1915
"dependencies": {
20-
"@cloudflare/sandbox": "^0.3.3",
2116
"openai": "^5.12.0"
2217
}
2318
}

0 commit comments

Comments
 (0)