← Sandbox SDK / sandbox / 1-0-preview / api
Procesy
Spouštějte a sledujte kontrolované procesy v aktuálním kontejneru sandboxu.
Vysvětlení principu fungování najdete v Provádění procesů. Pro interaktivní vstup PTY a terminály v prohlížeči viz Terminály a Terminals API.
Popisovače procesů mají žádný standardní vstup. Použijte cwd, env, a argv (nebo explicitní shellový skript) pro neinteraktivní práci. Použijte terminál když potřebujete interaktivní PTY.
exec()
Spusťte proces z argv (spustitelný soubor, poté argumenty). Vyřeší se ve chvíli, kdy se spuštění zdaří, nikoli až proces skončí. SDK nespouští shell a neprovádí shell escaping hodnot v argv, každý prvek představuje jeden argument procesu.
exec(command: SandboxCommand, options?: ExecOptions): Promise<SandboxProcess>SandboxCommand
type SandboxCommand = readonly [executable: string, ...args: string[]];command[0]musí být neprázdná cesta ke spustitelnému souboru nebo jeho název.- Pozdější argumenty mohou být prázdné řetězce.
- Položky se předávají v nezměněné podobě (bez shellového escapování argv).
- Syntaxe shellu vyžaduje explicitní shell, například
['/bin/bash', '-lc', script].
ExecOptions
| Pole | Typ | Popis |
|---|---|---|
cwd |
string |
Pracovní adresář pro toto spuštění. Výchozí hodnota je /workspace když není nastavena. |
env |
Record<string, string> |
Překrytí prostředí pro toto spuštění. Neovlivní pozdější spuštění. Env na úrovni sandboxu se i tak použije. |
timeout |
number |
Doba života vzdáleného procesu v milisekundách. Supervisor může proces zastavit; dokončení může hlásit timedOut: true. |
Vrací
Promise<SandboxProcess>
const process = await sandbox.exec(["node", "--version"]);
const output = await process.output({ encoding: "utf8" });
console.log(process.id, process.pid, output.stdout, output.exitCode);const process = await sandbox.exec(["node", "--version"]);
const output = await process.output({ encoding: "utf8" });
console.log(process.id, process.pid, output.stdout, output.exitCode);getProcess()
Vrátí popisovač procesu běžícího v aktuální kontejner pro tento sandbox, nebo null.
Pokud neběží žádný kontejner, nespustí nový. Vrátí null když neběží žádný kontejner, když je ID procesu v aktuálním kontejneru neznámé nebo když daný proces patřil předchozímu kontejneru se stejným ID sandboxu.
getProcess(id: string): Promise<SandboxProcess | null>ID procesů nejsou trvalá napříč zastavením nebo nahrazením kontejneru. Viz Jak dlouho proces žije.
listProcesses()
Vypíše procesy v aktuálním kontejneru tohoto sandboxu. Pokud žádný kontejner neběží, nespustí ho. Pokud žádný kontejner neběží, vrátí prázdný seznam.
listProcesses(): Promise<ProcessStatus[]>Každá položka je ProcessStatus hodnota (stejná struktura jako status()).
SandboxProcess
| Člen | Popis |
|---|---|
id |
ID procesu v aktuálním kontejneru. |
pid |
PID kontejneru při spuštění. |
exitCode |
Promise<number> který se vyřeší, jakmile se sledovaná skupina procesů ustálí. |
status() |
Aktuální rozlišený stav. |
logs(options?) |
Proud logů založený na kurzoru. |
output(options?) |
Bufferované stdout a stderr plus metadata o ukončení. |
waitForExit(options?) |
Počkejte, až se sledovaná skupina procesů ustálí. |
waitForLog(pattern, options?) |
Počkejte, až stdout nebo stderr odpovídá vzoru. |
waitForPort(port, options?) |
Počkejte, až bude port připraven, nebo dokud kontrola připravenosti neselže. |
kill(signal?) |
Odešlete číselný signál. Výchozí 15 (SIGTERM). |
Toto handle nemá API pro process stdin.
status()
status(): Promise<ProcessStatus>Viz ProcessStatus. Proces zůstává running dokud sledovaný skupina procesů se ustálí, i když kořenový pid skončí, zatímco potomci pokračují.
output()
Ukládejte stdout a stderr do bufferu, dokud proces neskončí (nebo neskončí místní čekání), a poté vraťte metadata o ukončení.
output(options?: ProcessOutputOptions): Promise<ProcessOutput<Uint8Array>>
output(
options: ProcessOutputOptions & { encoding: "utf8" },
): Promise<ProcessOutput<string>>ProcessOutput
interface ProcessOutput<T = Uint8Array> {
stdout: T;
stderr: T;
exitCode: number;
signal?: number;
timedOut: boolean;
truncated: boolean;
}Výchozí kódování těla je binární (Uint8Array) pokud nepředáte encoding: "utf8". Upřednostněte logs() když výstup může přesáhnout to, co chcete ukládat do bufferu.
ProcessOutputOptions
| Pole | Typ | Popis |
|---|---|---|
encoding |
"utf8" |
Dekódujte stdout/stderr jako řetězce. |
maxBytes |
number |
Omezte počet bufferovaných bajtů na každou stranu streamu výsledku; můžete nastavit truncated: true. Pokud je vynecháno, výchozí limit neplatí. |
timeout |
number |
Pouze lokální lhůta čekání v milisekundách; proces se neukončí. |
signal |
AbortSignal |
Zrušte pouze toto čekání; proces tím neukončíte. |
maxBytes musí být nezáporné konečné číslo, pokud je nastaveno.
const process = await sandbox.exec(["/bin/bash", "-lc", "npm test"], {
cwd: "/workspace/app",
});
const result = await process.output({ encoding: "utf8", timeout: 120_000 });
console.log(result.exitCode, result.stdout, result.timedOut, result.truncated);const process = await sandbox.exec(["/bin/bash", "-lc", "npm test"], {
cwd: "/workspace/app",
});
const result = await process.output({ encoding: "utf8", timeout: 120_000 });
console.log(result.exitCode, result.stdout, result.timedOut, result.truncated);logs()
Streamujte přehratelné události protokolu pomocí neprůhledného kurzoru.
logs(options?: ProcessLogsOptions): Promise<ReadableStream<ProcessLogEvent>>ProcessLogsOptions
| Pole | Typ | Popis |
|---|---|---|
since |
string |
Neprůhledný kurzor; pokračuje po předchozí události. |
replay |
boolean |
Při obnovení zahrne historii uloženou ve vyrovnávací paměti. |
follow |
boolean |
Udržujte stream otevřený pro živý výstup. |
signal |
AbortSignal |
Zrušte pouze tento odběr; proces poběží dál. |
ProcessLogEvent
type ProcessLogEvent =
| {
type: "stdout" | "stderr";
cursor: string;
timestamp: string;
data: Uint8Array;
}
| {
type: "terminal";
state: "exited";
cursor: string;
timestamp: string;
exit: ProcessExit;
}
| {
type: "terminal";
state: "error";
cursor: string;
timestamp: string;
error: ProcessFailure;
}
| {
type: "truncated";
cursor?: string;
timestamp: string;
};Ponechte nejnovější cursor z doručených událostí, pokud pozdější požadavek Workeru pokračuje s logs({ since: cursor, replay: true, follow: true }) na stejný proces v stejný kontejner.
const process = await sandbox.exec(["/bin/bash", "-lc", "npm run dev"], {
cwd: "/workspace/app",
});
const stream = await process.logs({ follow: true, replay: true });
const reader = stream.getReader();
const decoder = new TextDecoder();
for (;;) {
const { done, value } = await reader.read();
if (done) break;
if (value.type === "stdout" || value.type === "stderr") {
// Keep value.cursor if you will resume later
console.log(value.type, decoder.decode(value.data, { stream: true }));
continue;
}
if (value.type === "terminal") {
console.log("done", value.state);
break;
}
}const process = await sandbox.exec(["/bin/bash", "-lc", "npm run dev"], {
cwd: "/workspace/app",
});
const stream = await process.logs({ follow: true, replay: true });
const reader = stream.getReader();
const decoder = new TextDecoder();
for (;;) {
const { done, value } = await reader.read();
if (done) break;
if (value.type === "stdout" || value.type === "stderr") {
// Keep value.cursor if you will resume later
console.log(value.type, decoder.decode(value.data, { stream: true }));
continue;
}
if (value.type === "terminal") {
console.log("done", value.state);
break;
}
}waitForExit()
Počkejte, až se sledovaná skupina procesů ustálí.
waitForExit(options?: {
timeout?: number;
signal?: AbortSignal;
}): Promise<ProcessExit>| Pole | Typ | Popis |
|---|---|---|
timeout |
number |
Pouze lokální lhůta čekání; proces se neukončí. |
signal |
AbortSignal |
Zrušte pouze toto čekání; proces tím neukončíte. |
Vrátí ProcessExit. Místní vypršení časového limitu se projeví jako ProcessWaitTimeoutError. Místní přerušení se projeví jako ProcessAbortedError.
const build = await sandbox.exec(["/bin/bash", "-lc", "npm run build"], {
cwd: "/workspace/app",
});
const exit = await build.waitForExit({ timeout: 600_000 });
console.log(exit.code, exit.signal, exit.timedOut);const build = await sandbox.exec(["/bin/bash", "-lc", "npm run build"], {
cwd: "/workspace/app",
});
const exit = await build.waitForExit({ timeout: 600_000 });
console.log(exit.code, exit.signal, exit.timedOut);waitForLog()
Počkejte, až stdout a/nebo stderr odpovídá danému vzoru.
waitForLog(
pattern: string | RegExp,
options?: WaitForLogOptions,
): Promise<WaitForLogResult>WaitForLogOptions
| Pole | Typ | Popis |
|---|---|---|
stream |
"stdout" | "stderr" | "both" |
Které streamy se mají shodovat. Výchozí: "both". |
timeout |
number |
Pouze lokální lhůta čekání; proces se neukončí. |
signal |
AbortSignal |
Zrušte pouze toto čekání; proces tím neukončíte. |
WaitForLogResult
interface WaitForLogResult {
stream: "stdout" | "stderr";
text: string;
match: string;
cursor?: string;
}textje odpovídající okno dekódovaného výstupu pro daný stream.matchje odpovídající podřetězec.cursorje kurzor v logu na místě shody, pokud je k dispozici.
Pokud proces skončí dříve, než dojde ke shodě, SDK vyvolá ProcessExitedBeforeLogError. Místní časový limit čekání vyvolá ProcessWaitTimeoutError.
const server = await sandbox.exec(["/bin/bash", "-lc", "npm run dev"], {
cwd: "/workspace/app",
});
const ready = await server.waitForLog(/listening on/i, {
stream: "both",
timeout: 60_000,
});
console.log(ready.stream, ready.match);const server = await sandbox.exec(["/bin/bash", "-lc", "npm run dev"], {
cwd: "/workspace/app",
});
const ready = await server.waitForLog(/listening on/i, {
stream: "both",
timeout: 60_000,
});
console.log(ready.stream, ready.match);waitForPort()
Počkejte, až bude port připraven, nebo selžte, pokud proces skončí dříve nebo pokud skončí lokální čekání.
waitForPort(port: number, options?: WaitForPortOptions): Promise<void>WaitForPortOptions
| Pole | Typ | Popis |
|---|---|---|
mode |
"tcp" | "http" |
Kontrola připravenosti. Výchozí hodnota: "tcp" (přijímá TCP spojení). |
path |
string |
Cesta HTTP pro požadavek, když mode je "http". Výchozí hodnota: "/". |
status |
number | { min: number; max: number } |
Očekávaný stav HTTP nebo uzavřený rozsah, když mode je "http". Výchozí hodnota: { min: 200, max: 399 }. |
interval |
number |
Milisekundy mezi kontrolami. Výchozí hodnota: 500. |
timeout |
number |
Pouze lokální lhůta čekání; proces se neukončí. Při vynechání neplatí žádný výchozí časový limit. |
signal |
AbortSignal |
Zrušte pouze toto čekání; proces tím neukončíte. |
Režim TCP (výchozí) je úspěšná, jakmile port přijme spojení:
const db = await sandbox.exec(["redis-server"]);
await db.waitForPort(6379, {
mode: "tcp",
timeout: 10_000,
});const db = await sandbox.exec(["redis-server"]);
await db.waitForPort(6379, {
mode: "tcp",
timeout: 10_000,
});Režim HTTP odešle HTTP požadavek a zkontroluje stav odpovědi:
const server = await sandbox.exec(["/bin/bash", "-lc", "npm run dev"], {
cwd: "/workspace/app",
});
await server.waitForPort(3000, {
mode: "http",
path: "/health",
status: { min: 200, max: 299 },
timeout: 60_000,
});const server = await sandbox.exec(["/bin/bash", "-lc", "npm run dev"], {
cwd: "/workspace/app",
});
await server.waitForPort(3000, {
mode: "http",
path: "/health",
status: { min: 200, max: 299 },
timeout: 60_000,
});Typická selhání:
ProcessReadyTimeoutError: port nebyl připravený před vypršením lokálního timeoutuProcessExitedBeforeReadyError: proces skončil dříve, než byl port připravenýProcessAbortedError: lokálníAbortSignalzrušeno čekání (proces může stále běžet)
kill()
Odešlete procesu číselný signál.
kill(signal?: number): Promise<void>Výchozí signal je 15 (SIGTERM). Předejte pouze číselný signál (například 9 pro SIGKILL). Řetězcové názvy signálů nejsou podporovány.
Zastavení procesu je nezávislé na zrušení lokálního čekání nebo odběru logů.
exitCode
readonly exitCode: Promise<number>Vyřeší se s návratovým kódem ve chvíli, kdy se sledovaná skupina procesů ustálí (stejná hranice dokončení jako u waitForExit()). Upřednostněte waitForExit() když navíc potřebujete signal nebo timedOut.
ProcessStatus
type ProcessStatus =
| {
state: "running";
id: string;
pid: number;
command: SandboxCommand;
cwd?: string;
startedAt: string;
}
| {
state: "exited";
id: string;
pid: number;
command: SandboxCommand;
cwd?: string;
startedAt: string;
endedAt: string;
exit: ProcessExit;
}
| {
state: "error";
id: string;
pid: number;
command: SandboxCommand;
cwd?: string;
startedAt: string;
endedAt: string;
error: ProcessFailure;
};listProcesses() vrací ProcessStatus[] s touto strukturou.
ProcessExit
Pozorovaný výsledek pro kořen podproces, jakmile se sledovaná skupina ustálí.
interface ProcessExit {
code: number;
signal?: number;
timedOut: boolean;
}Signály doručené pouze potomkům tento výsledek nemění. Viz Provádění procesů.
ProcessFailure
interface ProcessFailure {
code: string;
message: string;
}Časté chyby
getProcess a listProcesses nevyvolávají chybu pro chybějící úlohu. Vrací null nebo [] když neběží žádný kontejner, když je ID v aktuálním kontejneru neznámé nebo když proces patřil předchozímu kontejneru. Následující třídy chyb platí pro operace nad handle procesu (a pro spuštění), nikoli pro tato vyhledávání.
| Situace | Třída / výsledek |
|---|---|
getProcess / listProcesses zatímco neběží žádný kontejner |
null / [] (nejde o chybu; nespouští kontejner) |
getProcess pro neznámé ID nebo proces z předchozího kontejneru |
null |
| Operace na handle poté, co byl kontejner nahrazen | StaleProcessHandleError |
| Operace na handle, když proces v aktuálním kontejneru už neexistuje | ProcessNotFoundError |
Vypršel časový limit lokálního čekání (output / waitForExit / waitForLog) |
ProcessWaitTimeoutError |
Lokální AbortSignal u čekání nebo streamu |
ProcessAbortedError |
| Port nebyl připravený před vypršením místního časového limitu | ProcessReadyTimeoutError |
| Proces skončil dříve, než byl port připravený | ProcessExitedBeforeReadyError |
| Proces skončil dříve, než došlo ke shodě v protokolu | ProcessExitedBeforeLogError |
| Neplatný pracovní adresář při spuštění | InvalidProcessCwdError |
| Neplatné prostředí při spuštění | InvalidProcessEnvironmentError |
| Neplatný kurzor protokolu | InvalidProcessCursorError |
| Spuštění procesu se nezdařilo | ProcessSpawnFailedError |
| Kontejner není připraven; práce nebyla zahájena | ContainerUnavailableError |
| Práce přerušená poté, co už možná začala | OperationInterruptedError |
Pokyny k obnovení: Chyby a zotavení. Úplný katalog: API chyb. Životnost: Jak dlouho proces žije.