# Long-Running Processes

`execute` and `evaluate` wait for your code to finish, so a server started that
way runs until `timeoutMs` and returns `timed_out`. For code that is meant to
keep running, `spawn` it in a [VM](/secure-exec/docs/vms).

## Spawn a background process

`spawn` returns as soon as the process is running.

secure-exec/examples/dev-server/src/index.ts:

```ts
import { createVm } from "secure-exec";

// The server is user-authored code, so it runs in a VM. Guest listeners stay on
// the VM's virtual network and do not need external network access.
const vm = await createVm();

// `spawn` returns as soon as the process starts, instead of waiting for the
// code to finish. The server prints a line once it is listening, so the host
// knows when it can send requests.
const ready = Promise.withResolvers<void>();
const decoder = new TextDecoder();
const server = await vm.javascript.spawn(
	`
	import { createServer } from "node:http";

	createServer((request, response) => {
		response.setHeader("content-type", "application/json");
		response.end(JSON.stringify({ path: request.url, pid: process.pid }));
	}).listen(3000, () => console.log("listening"));
	`,
	{
		onStdout: (chunk) => {
			if (decoder.decode(chunk).includes("listening")) ready.resolve();
		},
	},
);
console.log("server pid:", server.pid);
await ready.promise;
```

`vm.typescript.spawn` does the same for TypeScript source, and `spawnFile` for
a file that is already in the VM.

## What a spawned process shares

A spawned process is its own program in the VM, like a process on Linux.

| Shared with everything else in the VM | Not shared |
|---|---|
| The filesystem, including files you write from the host | JavaScript memory, including any [context](/secure-exec/docs/contexts) |
| Installed npm packages | |
| The virtual network, so other code in the VM can reach its ports | |

Other calls keep working while it runs. Code in the same VM can reach the
process on `127.0.0.1`, which makes a spawned server a good home for state that
several calls or contexts need to share.

## Reach it from the host

`vm.network.httpRequest` sends a request to a port inside the VM. Nothing is
exposed on the host's own network.

secure-exec/examples/dev-server/src/index.ts:

```ts
// Send requests from the host to the port inside the VM. Nothing is exposed on
// the host's own network.
const response = await vm.network.httpRequest({ port: 3000, path: "/hello" });
console.log(new TextDecoder().decode(response.body)); // {"path":"/hello","pid":...}
```

## Manage the process

`vm.process` controls processes by `pid`.

secure-exec/examples/dev-server/src/index.ts:

```ts
// Stop the server, then dispose the VM.
await vm.process.kill(server.pid);
const exit = await vm.process.wait(server.pid);
console.log("server exited:", exit);
await vm.dispose();
```

`wait(pid)` resolves when the process exits, `kill(pid)` and `signal(pid, signal)`
stop it, and `list()` shows what is running. `onStdout` and `onStderr` on
`spawn` stream its output live. Stop spawned processes before you dispose the
VM.

Read the [agentOS processes docs](/agentos/docs/processes) for the full process
model.
