MCPcopy Create free account
hub / github.com/cloudflare/computer / Runner

Class Runner

packages/computerd/src/exec/runner.ts:72–486  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

70}
71
72export class Runner {
73 private readonly db: Database;
74 private readonly opts: {
75 cwd: string | undefined;
76 env: Record<string, string> | undefined;
77 logMaxBytes: number;
78 retentionMs: number;
79 sweepIntervalMs: number;
80 defaultTimeoutMs: number;
81 heartbeatIntervalMs: number;
82 now: () => number;
83 };
84 private readonly records = new Map<string, ExecRecord>();
85 private sweepTimer: NodeJS.Timeout | undefined;
86 private disposed = false;
87
88 constructor(init: RunnerInit) {
89 this.db = init.db;
90 this.opts = {
91 cwd: init.cwd,
92 env: init.env,
93 logMaxBytes: init.logMaxBytes ?? DEFAULTS.logMaxBytes,
94 retentionMs: init.retentionMs ?? DEFAULTS.retentionMs,
95 sweepIntervalMs: init.sweepIntervalMs ?? DEFAULTS.sweepIntervalMs,
96 defaultTimeoutMs: init.defaultTimeoutMs ?? DEFAULTS.defaultTimeoutMs,
97 heartbeatIntervalMs: init.heartbeatIntervalMs ?? 0,
98 now: init.now ?? Date.now,
99 };
100 initializeExecSchema(this.db);
101 if (init.resetSchema !== false) clearExecState(this.db);
102 }
103
104 exec(command: string, options: ExecOptions = {}): ExecHandle {
105 if (this.disposed) throw new Error("runner disposed");
106 const id = options.id ?? randomUUID();
107 const existing = this.records.get(id);
108 if (existing?.live) {
109 throw new ExecError("EEXEC_BUSY", `exec id ${id} is already running`);
110 }
111 if (existing !== undefined) this.disposeRecord(existing);
112
113 const cwd = options.cwd ?? this.opts.cwd;
114 const env = { ...process.env, ...this.opts.env, ...options.env };
115 // Pre-flight the cwd via dofs's stat which walks vfs_nodes /
116 // vfs_dirents in SQLite directly — no node:fs.statSync, no
117 // FUSE callback. Preserves the historical ENOENT-cwd error
118 // shape callers see when the path doesn't exist, without
119 // taking a route that could deadlock against computerd's own FUSE
120 // server.
121 if (cwd !== undefined) {
122 try {
123 stat(this.db, cwd);
124 } catch (err) {
125 return this.spawnFailed(id, err);
126 }
127 }
128 // Don't pass cwd to spawn. libuv's uv_spawn does fork +
129 // chdir + execve in the child while the parent blocks on a

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected