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

Method doEnsureReady

src/node/runtime/CoderSSHRuntime.ts:270–415  ·  view source on GitHub ↗

* Core ensureReady logic - called once (protected by ensureReadyPromise). * * Flow: * 1. Check status via `coder list` - short-circuit for "running" or "not_found" * 2. If "stopping"/"canceling": poll until it clears (coder ssh can't autostart during these) * 3. Run `coder ssh --wait=

(
    workspaceName: string,
    options?: EnsureReadyOptions
  )

Source from the content-addressed store, hash-verified

268 * - starting/pending: waits for build completion + startup scripts
269 */
270 private async doEnsureReady(
271 workspaceName: string,
272 options?: EnsureReadyOptions
273 ): Promise<EnsureReadyResult> {
274 const statusSink = options?.statusSink;
275 const signal = options?.signal;
276 const startTime = Date.now();
277
278 const emitStatus = (phase: RuntimeStatusEvent["phase"], detail?: string) => {
279 statusSink?.({ phase, runtimeType: "ssh", detail });
280 };
281
282 // Helper: check if we've exceeded overall timeout
283 const isTimedOut = () => Date.now() - startTime > CODER_ENSURE_READY_TIMEOUT_MS;
284 const remainingMs = () => Math.max(0, CODER_ENSURE_READY_TIMEOUT_MS - (Date.now() - startTime));
285
286 // Step 1: Check current status for short-circuits
287 emitStatus("checking");
288
289 if (signal?.aborted) {
290 emitStatus("error");
291 return { ready: false, error: "Aborted", errorType: "runtime_start_failed" };
292 }
293
294 let statusResult = await this.coderService.getWorkspaceStatus(workspaceName, {
295 timeoutMs: Math.min(remainingMs(), 10_000),
296 signal,
297 });
298
299 // Short-circuit: already running
300 if (statusResult.kind === "ok" && statusResult.status === "running") {
301 return this.markReadyIfRepoPresent(workspaceName, options, emitStatus);
302 }
303
304 // Short-circuit: workspace doesn't exist
305 if (statusResult.kind === "not_found") {
306 emitStatus("error");
307 return this.coderWorkspaceNotFound(workspaceName);
308 }
309
310 // For status check errors (timeout, auth issues), proceed optimistically
311 // and let SSH fail naturally to avoid blocking the happy path
312 if (statusResult.kind === "error") {
313 if (signal?.aborted) {
314 emitStatus("error");
315 return { ready: false, error: "Aborted", errorType: "runtime_start_failed" };
316 }
317 log.debug("Coder workspace status unknown, proceeding optimistically", {
318 workspaceName,
319 error: statusResult.error,
320 });
321 }
322
323 // Step 2: Wait for "stopping"/"canceling" to clear (coder ssh can't autostart during these)
324 try {
325 statusResult = await this.waitForStoppingOrCancelingToClear(workspaceName, statusResult, {
326 abortSignal: signal,
327 timeoutMs: () => Math.min(remainingMs(), 10_000),

Callers 1

ensureReadyMethod · 0.95

Calls 11

isStoppingOrCancelingMethod · 0.95
getErrorMessageFunction · 0.90
getWorkspaceStatusMethod · 0.80
debugMethod · 0.80
waitForStartupScriptsMethod · 0.80
testMethod · 0.80
abortMethod · 0.65
addEventListenerMethod · 0.45

Tested by

no test coverage detected