INTEGRITY Dokumentace

Spouštění procesů na pozadí

Tato příručka ukazuje, jak v sandboxu spouštět dlouho běžící procesy na pozadí, sledovat je a spravovat.

Kdy použít procesy na pozadí

Použijte startProcess() místo exec() když:

Spuštění procesu na pozadí

import { getSandbox } from "@cloudflare/sandbox";

const sandbox = getSandbox(env.Sandbox, "my-sandbox");

// Start a web server
const server = await sandbox.startProcess("python -m http.server 8000");

console.log("Server started");
console.log("Process ID:", server.id);
console.log("PID:", server.pid);
console.log("Status:", server.status); // 'running'

// Process runs in background - your code continues
import { getSandbox } from '@cloudflare/sandbox';

const sandbox = getSandbox(env.Sandbox, 'my-sandbox');

// Start a web server
const server = await sandbox.startProcess('python -m http.server 8000');

console.log('Server started');
console.log('Process ID:', server.id);
console.log('PID:', server.pid);
console.log('Status:', server.status); // 'running'

// Process runs in background - your code continues

Nakonfigurujte prostředí procesu

Nastavte pracovní adresář a proměnné prostředí:

const process = await sandbox.startProcess("node server.js", {
	cwd: "/workspace/api",
	env: {
		NODE_ENV: "production",
		PORT: "8080",
		API_KEY: env.API_KEY,
		DATABASE_URL: env.DATABASE_URL,
	},
});

console.log("API server started");
const process = await sandbox.startProcess('node server.js', {
  cwd: '/workspace/api',
  env: {
    NODE_ENV: 'production',
    PORT: '8080',
    API_KEY: env.API_KEY,
    DATABASE_URL: env.DATABASE_URL
  }
});

console.log('API server started');

Sledování stavu procesu

Vypište a zkontrolujte běžící procesy:

const processes = await sandbox.listProcesses();

console.log(`Running ${processes.length} processes:`);

for (const proc of processes) {
	console.log(`${proc.id}: ${proc.command} (${proc.status})`);
}

// Check if specific process is running
const isRunning = processes.some(
	(p) => p.id === processId && p.status === "running",
);
const processes = await sandbox.listProcesses();

console.log(`Running ${processes.length} processes:`);

for (const proc of processes) {
  console.log(`${proc.id}: ${proc.command} (${proc.status})`);
}

// Check if specific process is running
const isRunning = processes.some(p => p.id === processId && p.status === 'running');

Čekání na připravenost procesu

Před pokračováním počkejte, až bude proces připraven:

const server = await sandbox.startProcess("node server.js");

// Wait for server to respond on port 3000
await server.waitForPort(3000);

console.log("Server is ready");
const server = await sandbox.startProcess('node server.js');

// Wait for server to respond on port 3000
await server.waitForPort(3000);

console.log('Server is ready');

Nebo počkejte na konkrétní vzory v protokolech:

const server = await sandbox.startProcess("node server.js");

// Wait for log message
const result = await server.waitForLog("Server listening");
console.log("Server is ready:", result.line);
const server = await sandbox.startProcess('node server.js');

// Wait for log message
const result = await server.waitForLog('Server listening');
console.log('Server is ready:', result.line);

Sledování protokolů procesu

Streamujte protokoly v reálném čase:

import { parseSSEStream } from "@cloudflare/sandbox";

const server = await sandbox.startProcess("node server.js");

// Stream logs
const logStream = await sandbox.streamProcessLogs(server.id);

for await (const log of parseSSEStream(logStream)) {
	console.log(log.data);
}
import { parseSSEStream, type LogEvent } from '@cloudflare/sandbox';

const server = await sandbox.startProcess('node server.js');

// Stream logs
const logStream = await sandbox.streamProcessLogs(server.id);

for await (const log of parseSSEStream<LogEvent>(logStream)) {
  console.log(log.data);
}

Nebo získejte nahromaděné protokoly:

const logs = await sandbox.getProcessLogs(server.id);
console.log("Logs:", logs);
const logs = await sandbox.getProcessLogs(server.id);
console.log('Logs:', logs);

Zastavení procesů

Zastavte procesy na pozadí a jejich potomky:

// Stop specific process (terminates entire process tree)
await sandbox.killProcess(server.id);

// Force kill if needed
await sandbox.killProcess(server.id, "SIGKILL");

// Stop all processes
await sandbox.killAllProcesses();
// Stop specific process (terminates entire process tree)
await sandbox.killProcess(server.id);

// Force kill if needed
await sandbox.killProcess(server.id, 'SIGKILL');

// Stop all processes
await sandbox.killAllProcesses();

killProcess() ukončí zadaný proces a všechny procesy, které z něj vznikly. Díky tomu procesy běžící na pozadí po ukončení nezanechávají osiřelé procesy potomků.

Pokud váš proces například spouští více pracovních procesů nebo úloh na pozadí, killProcess() vyčistí celý strom procesů:

// This script spawns multiple child processes
const batch = await sandbox.startProcess(
	'bash -c "process1 & process2 & process3 & wait"',
);

// killProcess() terminates the bash process AND all three child processes
await sandbox.killProcess(batch.id);
// This script spawns multiple child processes
const batch = await sandbox.startProcess(
  'bash -c "process1 & process2 & process3 & wait"'
);

// killProcess() terminates the bash process AND all three child processes
await sandbox.killProcess(batch.id);

Spouštění více procesů

Spouštějte služby postupně a vyčkejte na závislosti:

// Start database first
const db = await sandbox.startProcess("redis-server");

// Wait for database to be ready
await db.waitForPort(6379, { mode: "tcp" });

// Now start API server (depends on database)
const api = await sandbox.startProcess("node api-server.js", {
	env: { DATABASE_URL: "redis://localhost:6379" },
});

// Wait for API to be ready
await api.waitForPort(8080, { path: "/health" });

console.log("All services running");
// Start database first
const db = await sandbox.startProcess('redis-server');

// Wait for database to be ready
await db.waitForPort(6379, { mode: 'tcp' });

// Now start API server (depends on database)
const api = await sandbox.startProcess('node api-server.js', {
  env: { DATABASE_URL: 'redis://localhost:6379' }
});

// Wait for API to be ready
await api.waitForPort(8080, { path: '/health' });

console.log('All services running');

Udržujte kontejnery aktivní pro dlouho běžící procesy

Kontejnery se ve výchozím nastavení automaticky vypnou po 10 minutách nečinnosti. Pro dlouhotrvající procesy, které mohou mít období nečinnosti (například CI/CD pipeliny, dávkové úlohy nebo monitorovací úlohy), použijte keepAlive možnost:

import { getSandbox, parseSSEStream } from "@cloudflare/sandbox";

export { Sandbox } from "@cloudflare/sandbox";

export default {
	async fetch(request, env) {
		// Enable keepAlive for long-running processes
		const sandbox = getSandbox(env.Sandbox, "build-job-123", {
			keepAlive: true,
		});

		try {
			// Start a long-running build process
			const build = await sandbox.startProcess("npm run build:production");

			// Monitor progress
			const logs = await sandbox.streamProcessLogs(build.id);

			// Process can run indefinitely without container shutdown
			for await (const log of parseSSEStream(logs)) {
				console.log(log.data);
				if (log.data.includes("Build complete")) {
					break;
				}
			}

			return new Response("Build completed");
		} finally {
			// Important: Must explicitly destroy when done
			await sandbox.destroy();
		}
	},
};
import { getSandbox, parseSSEStream, type LogEvent } from '@cloudflare/sandbox';

export { Sandbox } from '@cloudflare/sandbox';

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    // Enable keepAlive for long-running processes
    const sandbox = getSandbox(env.Sandbox, 'build-job-123', {
      keepAlive: true
    });

    try {
      // Start a long-running build process
      const build = await sandbox.startProcess('npm run build:production');

      // Monitor progress
      const logs = await sandbox.streamProcessLogs(build.id);

      // Process can run indefinitely without container shutdown
      for await (const log of parseSSEStream<LogEvent>(logs)) {
        console.log(log.data);
        if (log.data.includes('Build complete')) {
          break;
        }
      }

      return new Response('Build completed');
    } finally {
      // Important: Must explicitly destroy when done
      await sandbox.destroy();
    }
  }
};

Osvědčené postupy

Řešení potíží

Proces se okamžitě ukončí

Příčinu zjistíte v protokolech:

const process = await sandbox.startProcess("node server.js");
await new Promise((resolve) => setTimeout(resolve, 1000));

const processes = await sandbox.listProcesses();
if (!processes.find((p) => p.id === process.id)) {
	const logs = await sandbox.getProcessLogs(process.id);
	console.error("Process exited:", logs);
}
const process = await sandbox.startProcess('node server.js');
await new Promise(resolve => setTimeout(resolve, 1000));

const processes = await sandbox.listProcesses();
if (!processes.find(p => p.id === process.id)) {
  const logs = await sandbox.getProcessLogs(process.id);
  console.error('Process exited:', logs);
}

Port je již používaný

Před spuštěním ukončete existující procesy:

await sandbox.killAllProcesses();
const server = await sandbox.startProcess("node server.js");
await sandbox.killAllProcesses();
const server = await sandbox.startProcess('node server.js');