Aller au contenu principal

SandboxProcessManager

Ajouté dans : @mastra/core@1.7.0

Classe de base abstraite permettant de gérer les processus en arrière-plan dans les Sandboxes. Elle fournit des méthodes pour lancer les processus, les répertorier, récupérer leurs handles à partir du PID et les arrêter.

BlaxelSandbox, DaytonaSandbox, E2BSandbox, ModalSandbox et LocalSandbox comprennent tous un gestionnaire de processus intégré. Vous n'avez pas besoin d'instancier directement cette classe, sauf si vous créez un Provider de Sandbox personnalisé.

Exemple d'utilisation
Lien direct vers Exemple d'utilisation

Accédez au gestionnaire de processus au moyen de la propriété processes de la Sandbox :

src/mastra/index.ts
import { LocalSandbox } from '@mastra/core/workspace'

const sandbox = new LocalSandbox({ workingDirectory: './workspace' })
await sandbox.start()

// Spawn a background process
const handle = await sandbox.processes.spawn('node server.js', {
env: { PORT: '3000' },
onStdout: data => console.log(data),
})

// List all tracked processes
const procs = await sandbox.processes.list()

// Get a handle by PID
const proc = await sandbox.processes.get(handle.pid)

// Kill a process
await sandbox.processes.kill(handle.pid)

Méthodes
Lien direct vers Méthodes

spawn(command, options?)
Lien direct vers spawncommand-options

Lance un processus en arrière-plan. Renvoie immédiatement un ProcessHandle sans attendre la fin du processus.

const handle = await sandbox.processes.spawn('npm run dev', {
cwd: '/app',
env: { NODE_ENV: 'development' },
onStdout: data => console.log(data),
})

Paramètres :

command:

string
Commande à exécuter. Interprétée par le shell.

options?:

SpawnProcessOptions
Paramètres facultatifs du processus lancé.
SpawnProcessOptions

timeout?:

number
Délai d'expiration en millisecondes. Arrête le processus en cas de dépassement.

env?:

NodeJS.ProcessEnv
Variables d'environnement du processus.

cwd?:

string
Répertoire de travail du processus.

onStdout?:

(data: string) => void
Callback pour les fragments de stdout. Appelé à mesure que les données arrivent.

onStderr?:

(data: string) => void
Callback pour les fragments de stderr. Appelé à mesure que les données arrivent.

abortSignal?:

AbortSignal
Signal permettant d'abandonner le processus. Lorsqu'il est déclenché, le processus est arrêté.

Renvoie : Promise<ProcessHandle>

list()
Lien direct vers list

Répertorie tous les processus suivis. Renvoie des informations sur chaque processus, notamment son PID, son état d'exécution et son code de sortie.

const procs = await sandbox.processes.list()
for (const proc of procs) {
console.log(proc.pid, proc.running, proc.exitCode)
}

Renvoie : Promise<ProcessInfo[]>

get(pid)
Lien direct vers getpid

Récupère le handle d'un processus à partir de son PID. Renvoie undefined si le processus est introuvable ou a déjà été retiré.

const handle = await sandbox.processes.get(1234)
if (handle) {
console.log(handle.stdout)
await handle.kill()
}

Renvoie : Promise<ProcessHandle | undefined>

kill(pid)
Lien direct vers killpid

Arrête un processus à partir de son PID. Attend la fin du processus avant de renvoyer le résultat. Renvoie true si le processus a été arrêté et false s'il est introuvable.

const killed = await sandbox.processes.kill(handle.pid)

Renvoie : Promise<boolean>

ProcessInfo
Lien direct vers processinfo

Informations sur un processus suivi, renvoyées par list().

pid:

number
Identifiant du processus.

command?:

string
Commande qui a été exécutée.

running:

boolean
Indique si le processus est toujours en cours d'exécution.

exitCode?:

number
Code de sortie si le processus est terminé.

ProcessHandle
Lien direct vers processhandle

Handle d'un processus lancé en arrière-plan. Fournit des méthodes pour lire la sortie, envoyer des données sur stdin, attendre la fin et arrêter le processus.

Vous ne créez pas directement d'instances de ProcessHandle. Elles sont renvoyées par spawn() et get().

Exemple d'utilisation
Lien direct vers Exemple d'utilisation

const handle = await sandbox.processes.spawn('npm run dev', {
onStdout: data => console.log(data),
})

// Read accumulated output
console.log(handle.pid)
console.log(handle.stdout)
console.log(handle.stderr)
console.log(handle.exitCode) // undefined while running

// Wait for completion
const result = await handle.wait()

// Send stdin
await handle.sendStdin('input data\n')

// Kill the process
await handle.kill()

Propriétés
Lien direct vers Propriétés

pid:

number
Identifiant du processus.

stdout:

string
Sortie stdout accumulée jusque-là.

stderr:

string
Sortie stderr accumulée jusque-là.

exitCode:

number | undefined
Code de sortie. undefined tant que le processus est en cours d'exécution.

command:

string | undefined
Commande qui a été lancée. Définie automatiquement par le gestionnaire de processus.

reader:

Readable
Stream lisible de stdout. Utile pour les protocoles tels que LSP ou JSON-RPC qui communiquent via stdio.

writer:

Writable
Stream inscriptible vers stdin. Utile pour les protocoles tels que LSP ou JSON-RPC qui communiquent via stdio.

Méthodes
Lien direct vers Méthodes

wait(options?)
Lien direct vers waitoptions

Attend la fin du processus et renvoie le résultat. Vous pouvez transmettre des callbacks onStdout/onStderr pour diffuser la sortie pendant l'attente. Les callbacks sont automatiquement supprimés lorsque wait() est résolue.

// Simple wait
const result = await handle.wait()
console.log(result.success, result.exitCode, result.stdout)

// Wait with streaming
const result = await handle.wait({
onStdout: data => process.stdout.write(data),
onStderr: data => process.stderr.write(data),
})

Paramètres :

options?:

WaitOptions
Paramètres facultatifs de l'attente.
WaitOptions

onStdout?:

(data: string) => void
Callback pour les fragments de stdout pendant l'attente.

onStderr?:

(data: string) => void
Callback pour les fragments de stderr pendant l'attente.

Renvoie : Promise<CommandResult>

L'objet CommandResult contient :

success:

boolean
true si le code de sortie est 0.

exitCode:

number
Code de sortie numérique.

stdout:

string
Sortie stdout complète.

stderr:

string
Sortie stderr complète.

executionTimeMs:

number
Durée d'exécution en millisecondes.

timedOut?:

boolean
true si le processus a été arrêté en raison d'un délai d'expiration.

killed?:

boolean
true si le processus a été arrêté par un signal.

kill()
Lien direct vers kill

Arrête le processus. Renvoie true si le processus a été arrêté et false s'il était déjà terminé.

const killed = await handle.kill()

Renvoie : Promise<boolean>

sendStdin(data)
Lien direct vers sendstdindata

Envoie des données sur le stdin du processus. Lève une erreur si le processus est déjà terminé ou si stdin n'est pas disponible.

await handle.sendStdin('console.log("hello")\n')

Renvoie : Promise<void>

Interopérabilité des streams
Lien direct vers Interopérabilité des streams

ProcessHandle expose les propriétés reader et writer pour l'intégration avec des protocoles Node.js fondés sur des streams, tels que LSP ou JSON-RPC :

import {
createMessageConnection,
StreamMessageReader,
StreamMessageWriter,
} from 'vscode-jsonrpc/node'

const handle = await sandbox.processes.spawn('typescript-language-server --stdio')

const connection = createMessageConnection(
new StreamMessageReader(handle.reader),
new StreamMessageWriter(handle.writer),
)
connection.listen()

Création d'un gestionnaire de processus personnalisé
Lien direct vers Création d'un gestionnaire de processus personnalisé

Pour créer un gestionnaire de processus destiné à un Provider de Sandbox personnalisé, étendez SandboxProcessManager et implémentez spawn() et list(). La classe de base enveloppe automatiquement vos méthodes avec ensureRunning() afin que la Sandbox démarre avant toute opération sur un processus.

import { SandboxProcessManager, ProcessHandle } from '@mastra/core/workspace'
import type { ProcessInfo, SpawnProcessOptions } from '@mastra/core/workspace'

class MyProcessManager extends SandboxProcessManager<MySandbox> {
async spawn(command: string, options: SpawnProcessOptions = {}): Promise<ProcessHandle> {
// Your spawn implementation
const handle = new MyProcessHandle(/* ... */)
this._tracked.set(handle.pid, handle)
return handle
}

async list(): Promise<ProcessInfo[]> {
return Array.from(this._tracked.values()).map(handle => ({
pid: handle.pid,
running: handle.exitCode === undefined,
exitCode: handle.exitCode,
}))
}
}

Transmettez le gestionnaire de processus à votre Sandbox au moyen de l'option processes de MastraSandbox :

class MySandbox extends MastraSandbox {
constructor() {
super({
name: 'MySandbox',
processes: new MyProcessManager(),
})
}
}

Lorsqu'un gestionnaire de processus est fourni, MastraSandbox crée automatiquement une implémentation par défaut de executeCommand qui utilise spawn() + wait() ; vous n'avez donc pas besoin d'implémenter les deux.