MCPcopy
hub / github.com/coder/mux / deleteWorkspaceEventually

Method deleteWorkspaceEventually

src/node/services/coderService.ts:1388–1511  ·  view source on GitHub ↗

* Delete a Coder workspace, retrying across transient build states. * * This is used for "cancel creation" because aborting the local `coder create` * process does not guarantee the control-plane build is canceled.

(
    name: string,
    options?: {
      timeoutMs?: number;
      signal?: AbortSignal;
      /**
       * If true, treat an initial "not found" as inconclusive and keep polling.
       * This avoids races where `coder create` finishes server-side after mux aborts the CLI.
       */
      waitForExistence?: boolean;
      /**
       * When `waitForExistence` is true: if we only see "not found" for this many ms
       * without ever observing the workspace exist, treat it as success and return early.
       * Defaults to `timeoutMs` (no separate short-circuit).
       */
      waitForExistenceTimeoutMs?: number;
    }
  )

Source from the content-addressed store, hash-verified

1386 * process does not guarantee the control-plane build is canceled.
1387 */
1388 async deleteWorkspaceEventually(
1389 name: string,
1390 options?: {
1391 timeoutMs?: number;
1392 signal?: AbortSignal;
1393 /**
1394 * If true, treat an initial "not found" as inconclusive and keep polling.
1395 * This avoids races where `coder create` finishes server-side after mux aborts the CLI.
1396 */
1397 waitForExistence?: boolean;
1398 /**
1399 * When `waitForExistence` is true: if we only see "not found" for this many ms
1400 * without ever observing the workspace exist, treat it as success and return early.
1401 * Defaults to `timeoutMs` (no separate short-circuit).
1402 */
1403 waitForExistenceTimeoutMs?: number;
1404 }
1405 ): Promise<Result<void>> {
1406 const timeoutMs = options?.timeoutMs ?? 60_000;
1407 const startTime = Date.now();
1408
1409 // Safety: never delete Coder workspaces mux didn't create.
1410 // Mux-created workspaces always use the mux- prefix.
1411 if (!name.startsWith("mux-")) {
1412 log.warn("Refusing to delete Coder workspace without mux- prefix", { name });
1413 return Ok(undefined);
1414 }
1415
1416 const isTimedOut = () => Date.now() - startTime > timeoutMs;
1417 const remainingMs = () => Math.max(0, timeoutMs - (Date.now() - startTime));
1418
1419 const unstableStates = new Set<CoderWorkspaceStatus>([
1420 "starting",
1421 "pending",
1422 "stopping",
1423 "canceling",
1424 ]);
1425
1426 let sawWorkspaceExist = false;
1427 let lastError: string | undefined;
1428 let attempt = 0;
1429
1430 while (!isTimedOut()) {
1431 if (options?.signal?.aborted) {
1432 return Err("Delete operation aborted");
1433 }
1434
1435 const statusResult = await this.getWorkspaceStatus(name, {
1436 timeoutMs: Math.min(remainingMs(), 10_000),
1437 signal: options?.signal,
1438 });
1439
1440 if (statusResult.kind === "ok") {
1441 sawWorkspaceExist = true;
1442
1443 if (statusResult.status === "deleted" || statusResult.status === "deleting") {
1444 return Ok(undefined);
1445 }

Callers 3

deleteWorkspaceMethod · 0.95
deleteWorkspaceMethod · 0.80

Calls 8

getWorkspaceStatusMethod · 0.95
sleepMethod · 0.95
runCoderCommandMethod · 0.95
OkFunction · 0.90
ErrFunction · 0.90
interpretCoderResultFunction · 0.85
debugMethod · 0.80
hasMethod · 0.45

Tested by

no test coverage detected