MCPcopy Index your code
hub / github.com/coder/coder / waitForAgentReady

Function waitForAgentReady

coderd/x/chatd/chattool/createworkspace.go:619–704  ·  view source on GitHub ↗

waitForAgentReady waits for the workspace agent to become reachable and for its startup scripts to finish. It returns status fields suitable for merging into a tool response.

(
	ctx context.Context,
	db database.Store,
	agent database.WorkspaceAgent,
	agentConnFn AgentConnFunc,
)

Source from the content-addressed store, hash-verified

617// reachable and for its startup scripts to finish. It returns
618// status fields suitable for merging into a tool response.
619func waitForAgentReady(
620 ctx context.Context,
621 db database.Store,
622 agent database.WorkspaceAgent,
623 agentConnFn AgentConnFunc,
624) map[string]any {
625 result := map[string]any{}
626 agentID := agent.ID
627
628 // Phase 1: retry connecting to the agent.
629 if agentConnFn != nil {
630 agentCtx, agentCancel := context.WithTimeout(ctx, agentConnectTimeout)
631 defer agentCancel()
632
633 ticker := time.NewTicker(agentRetryInterval)
634 defer ticker.Stop()
635
636 var lastErr error
637 for {
638 attemptCtx, attemptCancel := context.WithTimeout(agentCtx, agentAttemptTimeout)
639 conn, release, err := agentConnFn(attemptCtx, agentID)
640 attemptCancel()
641 if err == nil {
642 release()
643 _ = conn
644 break
645 }
646 lastErr = err
647
648 select {
649 case <-agentCtx.Done():
650 result["agent_status"] = "not_ready"
651 // External agents may need user action on a different
652 // host. Surface that guidance instead of the raw dial
653 // error after the retry window has elapsed. The retry
654 // loop itself is unchanged, so a Connecting external
655 // agent still gets the full window to come online.
656 if msg := externalAgentReadyError(ctx, db, agent); msg != "" {
657 result["agent_error"] = msg
658 } else {
659 result["agent_error"] = lastErr.Error()
660 }
661 return result
662 case <-ticker.C:
663 }
664 }
665 }
666
667 // Phase 2: poll lifecycle until startup scripts finish.
668 scriptCtx, scriptCancel := context.WithTimeout(ctx, startupScriptTimeout)
669 defer scriptCancel()
670
671 ticker := time.NewTicker(startupScriptPollInterval)
672 defer ticker.Stop()
673
674 var lastState database.WorkspaceAgentLifecycleState
675 for {
676 row, err := db.GetWorkspaceAgentLifecycleStateByID(scriptCtx, agentID)

Callers 4

TestWaitForAgentReadyFunction · 0.85
CreateWorkspaceFunction · 0.85
waitForAgentAndRespondFunction · 0.85

Calls 7

externalAgentReadyErrorFunction · 0.85
ErrMethod · 0.80
StopMethod · 0.65
DoneMethod · 0.45
ErrorMethod · 0.45
IsMethod · 0.45

Tested by 1

TestWaitForAgentReadyFunction · 0.68