Skip to content

Commit 8918362

Browse files
Document process readiness feature
Add documentation for new waitForLog() and waitForPort() methods added to the Process interface. These methods allow users to wait for processes to become ready before continuing execution. Changes: - Add Process method reference documentation in commands.mdx - Update background-processes guide with readiness checking examples - Show error handling for ProcessReadyTimeoutError - Demonstrate regex pattern matching for log analysis - Include timeout configuration examples Related to cloudflare/sandbox-sdk#273 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 50504a5 commit 8918362

File tree

2 files changed

+204
-18
lines changed

2 files changed

+204
-18
lines changed

src/content/docs/sandbox/api/commands.mdx

Lines changed: 139 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ for await (const event of parseSSEStream<ExecEvent>(stream)) {
8787
Start a long-running background process.
8888

8989
```ts
90-
const process = await sandbox.startProcess(command: string, options?: ProcessOptions): Promise<ProcessInfo>
90+
const process = await sandbox.startProcess(command: string, options?: ProcessOptions): Promise<Process>
9191
```
9292

9393
**Parameters**:
@@ -96,7 +96,7 @@ const process = await sandbox.startProcess(command: string, options?: ProcessOpt
9696
- `cwd` - Working directory
9797
- `env` - Environment variables
9898

99-
**Returns**: `Promise<ProcessInfo>` with `id`, `pid`, `command`, `status`
99+
**Returns**: `Promise<Process>` with `id`, `pid`, `command`, `status`, and methods for process management
100100

101101
<TypeScriptExample>
102102
```
@@ -111,6 +111,143 @@ const app = await sandbox.startProcess('node app.js', {
111111
```
112112
</TypeScriptExample>
113113

114+
## Process methods
115+
116+
The `Process` object returned by `startProcess()` provides methods for managing the process lifecycle and checking readiness.
117+
118+
### `process.waitForLog()`
119+
120+
Wait for a log pattern to appear in process output. Useful for detecting when a service is ready.
121+
122+
```ts
123+
const result = await process.waitForLog(pattern: string | RegExp, timeout?: number): Promise<WaitForLogResult>
124+
```
125+
126+
**Parameters**:
127+
- `pattern` - String to match or RegExp pattern
128+
- `timeout` (optional) - Maximum wait time in milliseconds
129+
130+
**Returns**: `Promise<WaitForLogResult>` with `line` (matching line) and `match` (regex captures if using RegExp)
131+
132+
**Throws**:
133+
- `ProcessReadyTimeoutError` - Pattern not found within timeout
134+
- `ProcessExitedBeforeReadyError` - Process exited before pattern appeared
135+
136+
<TypeScriptExample>
137+
```
138+
// String pattern matching
139+
const server = await sandbox.startProcess('npm run dev');
140+
await server.waitForLog('Server listening on port 3000');
141+
console.log('Server is ready!');
142+
143+
// Regex pattern with timeout
144+
const result = await server.waitForLog(/listening on port (\d+)/, 30000);
145+
console.log('Port:', result.match[1]); // Extract port from regex capture
146+
147+
// Error handling
148+
import { ProcessReadyTimeoutError } from '@cloudflare/sandbox';
149+
150+
try {
151+
await server.waitForLog('Ready', 5000);
152+
} catch (error) {
153+
if (error instanceof ProcessReadyTimeoutError) {
154+
console.error('Server did not start within 5 seconds');
155+
const logs = await server.getLogs();
156+
console.error('Logs:', logs.stdout);
157+
}
158+
}
159+
```
160+
</TypeScriptExample>
161+
162+
### `process.waitForPort()`
163+
164+
Wait for a port to accept TCP connections. Useful for ensuring network services are ready.
165+
166+
```ts
167+
await process.waitForPort(port: number, timeout?: number): Promise<void>
168+
```
169+
170+
**Parameters**:
171+
- `port` - Port number to check
172+
- `timeout` (optional) - Maximum wait time in milliseconds
173+
174+
**Throws**:
175+
- `ProcessReadyTimeoutError` - Port did not become ready within timeout
176+
- `ProcessExitedBeforeReadyError` - Process exited before port opened
177+
178+
<TypeScriptExample>
179+
```
180+
const server = await sandbox.startProcess('node server.js');
181+
182+
// Wait for port to be ready
183+
await server.waitForPort(8080, 10000);
184+
console.log('Server is accepting connections on port 8080');
185+
186+
// Make requests to the service
187+
const response = await fetch('http://localhost:8080/health');
188+
```
189+
</TypeScriptExample>
190+
191+
### `process.getLogs()`
192+
193+
Get accumulated logs from the process.
194+
195+
```ts
196+
const logs = await process.getLogs(): Promise<{ stdout: string; stderr: string }>
197+
```
198+
199+
**Returns**: `Promise` with `stdout` and `stderr` strings
200+
201+
<TypeScriptExample>
202+
```
203+
const server = await sandbox.startProcess('node server.js');
204+
const logs = await server.getLogs();
205+
console.log('Output:', logs.stdout);
206+
console.log('Errors:', logs.stderr);
207+
```
208+
</TypeScriptExample>
209+
210+
### `process.getStatus()`
211+
212+
Get refreshed process status.
213+
214+
```ts
215+
const status = await process.getStatus(): Promise<ProcessStatus>
216+
```
217+
218+
**Returns**: `Promise<ProcessStatus>` - One of: `'starting'`, `'running'`, `'completed'`, `'failed'`, `'killed'`, `'error'`
219+
220+
<TypeScriptExample>
221+
```
222+
const server = await sandbox.startProcess('node server.js');
223+
const status = await server.getStatus();
224+
225+
if (status === 'running') {
226+
console.log('Process is still running');
227+
}
228+
```
229+
</TypeScriptExample>
230+
231+
### `process.kill()`
232+
233+
Terminate the process.
234+
235+
```ts
236+
await process.kill(signal?: string): Promise<void>
237+
```
238+
239+
**Parameters**:
240+
- `signal` (optional) - Signal to send (default: `'SIGTERM'`)
241+
242+
<TypeScriptExample>
243+
```
244+
const server = await sandbox.startProcess('node server.js');
245+
await server.kill(); // Graceful shutdown
246+
// or
247+
await server.kill('SIGKILL'); // Force kill
248+
```
249+
</TypeScriptExample>
250+
114251
### `listProcesses()`
115252

116253
List all running processes.

src/content/docs/sandbox/guides/background-processes.mdx

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -83,24 +83,76 @@ const isRunning = processes.some(p => p.id === processId && p.status === 'runnin
8383
```
8484
</TypeScriptExample>
8585

86-
## Monitor process logs
86+
## Wait for process readiness
8787

88-
Stream logs in real-time to detect when a service is ready:
88+
Use `waitForLog()` to detect when a service is ready by matching log output:
89+
90+
<TypeScriptExample>
91+
```
92+
const server = await sandbox.startProcess('node server.js');
93+
94+
// Wait for specific log message
95+
await server.waitForLog('Server listening on port 3000');
96+
console.log('Server is ready!');
97+
98+
// Or use regex to extract information
99+
const result = await server.waitForLog(/listening on port (\d+)/);
100+
console.log('Server started on port', result.match[1]);
101+
```
102+
</TypeScriptExample>
103+
104+
For network services, use `waitForPort()` to wait for a port to accept connections:
105+
106+
<TypeScriptExample>
107+
```
108+
const server = await sandbox.startProcess('python -m http.server 8000');
109+
110+
// Wait for port to be ready
111+
await server.waitForPort(8000);
112+
console.log('Server is accepting connections');
113+
114+
// Now safe to make requests
115+
const response = await fetch('http://localhost:8000');
116+
```
117+
</TypeScriptExample>
118+
119+
### Set timeouts for readiness checks
120+
121+
Specify a timeout to avoid waiting indefinitely:
122+
123+
<TypeScriptExample>
124+
```
125+
import { ProcessReadyTimeoutError } from '@cloudflare/sandbox';
126+
127+
try {
128+
// Wait up to 30 seconds
129+
await server.waitForLog('Ready', 30000);
130+
} catch (error) {
131+
if (error instanceof ProcessReadyTimeoutError) {
132+
console.error('Server did not start in time');
133+
const logs = await server.getLogs();
134+
console.error('Last output:', logs.stdout);
135+
}
136+
}
137+
```
138+
</TypeScriptExample>
139+
140+
### Manual log monitoring
141+
142+
For advanced scenarios, stream logs directly:
89143

90144
<TypeScriptExample>
91145
```
92146
import { parseSSEStream, type LogEvent } from '@cloudflare/sandbox';
93147
94148
const server = await sandbox.startProcess('node server.js');
95-
96-
// Stream logs
97149
const logStream = await sandbox.streamProcessLogs(server.id);
98150
99151
for await (const log of parseSSEStream<LogEvent>(logStream)) {
100152
console.log(log.data);
101153
154+
// Custom readiness logic
102155
if (log.data.includes('Server listening')) {
103-
console.log('Server is ready!');
104156
break;
105157
}
106158
}
@@ -111,8 +163,9 @@ Or get accumulated logs:
111163

112164
<TypeScriptExample>
113165
```
114-
const logs = await sandbox.getProcessLogs(server.id);
115-
console.log('Logs:', logs);
166+
const logs = await server.getLogs();
167+
console.log('Output:', logs.stdout);
168+
console.log('Errors:', logs.stderr);
116169
```
117170
</TypeScriptExample>
118171

@@ -137,25 +190,21 @@ Start services in sequence, waiting for dependencies:
137190

138191
<TypeScriptExample>
139192
```
140-
import { parseSSEStream, type LogEvent } from '@cloudflare/sandbox';
141-
142193
// Start database first
143194
const db = await sandbox.startProcess('redis-server');
144195
145196
// Wait for database to be ready
146-
const dbLogs = await sandbox.streamProcessLogs(db.id);
147-
for await (const log of parseSSEStream<LogEvent>(dbLogs)) {
148-
if (log.data.includes('Ready to accept connections')) {
149-
break;
150-
}
151-
}
197+
await db.waitForLog('Ready to accept connections');
198+
console.log('Database is ready');
152199
153200
// Now start API server (depends on database)
154201
const api = await sandbox.startProcess('node api-server.js', {
155202
env: { DATABASE_URL: 'redis://localhost:6379' }
156203
});
157204
158-
console.log('All services running');
205+
// Wait for API to be ready
206+
await api.waitForPort(3000);
207+
console.log('API server is accepting connections');
159208
```
160209
</TypeScriptExample>
161210

0 commit comments

Comments
 (0)