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

Function waitForProcess

coderd/x/chatd/chattool/execute.go:249–352  ·  view source on GitHub ↗

waitForProcess waits for process completion using the blocking process output API instead of polling. waitForProcess blocks until the process exits or the context expires. On any error (timeout or transport), it tries a non-blocking snapshot to recover. Total wall time may exceed timeout by up to sn

(
	ctx context.Context,
	parentCtx context.Context,
	conn workspacesdk.AgentConn,
	processID string,
	timeout time.Duration,
)

Source from the content-addressed store, hash-verified

247// non-blocking snapshot to recover. Total wall time may exceed
248// timeout by up to snapshotTimeout if recovery is needed.
249func waitForProcess(
250 ctx context.Context,
251 parentCtx context.Context,
252 conn workspacesdk.AgentConn,
253 processID string,
254 timeout time.Duration,
255) ExecuteResult {
256 // Block until the process exits or the context is
257 // canceled.
258 resp, err := conn.ProcessOutput(ctx, processID, &workspacesdk.ProcessOutputOptions{
259 Wait: true,
260 })
261 if err != nil {
262 origErr := err
263 timedOut := ctx.Err() != nil
264
265 // Fetch a snapshot with a fresh context. The blocking
266 // request may have failed due to a context timeout or
267 // a transport error (e.g. the server's WriteTimeout
268 // killed the connection). Either way, the process may
269 // still have output available.
270 bgCtx, bgCancel := context.WithTimeout(
271 parentCtx,
272 snapshotTimeout,
273 )
274 defer bgCancel()
275 resp, err = conn.ProcessOutput(bgCtx, processID, nil)
276 if err != nil {
277 errMsg := fmt.Sprintf("get process output: %v; use process_output with ID %s to retry", origErr, processID)
278 if timedOut {
279 errMsg = fmt.Sprintf("command timed out after %s; failed to get output: %v", timeout, err)
280 }
281 return ExecuteResult{
282 Success: false,
283 ExitCode: -1,
284 Error: errMsg,
285 BackgroundProcessID: processID,
286 }
287 }
288
289 // Snapshot succeeded. If the process finished, return
290 // its real result (transparent recovery).
291 if !resp.Running {
292 exitCode := 0
293 if resp.ExitCode != nil {
294 exitCode = *resp.ExitCode
295 }
296 output := truncateOutput(resp.Output)
297 return ExecuteResult{
298 Success: exitCode == 0,
299 Output: output,
300 ExitCode: exitCode,
301 Truncated: resp.Truncated,
302 }
303 }
304
305 // Process still running, return partial output.
306 output := truncateOutput(resp.Output)

Callers 1

executeForegroundFunction · 0.85

Calls 3

truncateOutputFunction · 0.85
ErrMethod · 0.80
ProcessOutputMethod · 0.65

Tested by

no test coverage detected