shouldPropagateError decides whether an error from an API connection routine should be propagated to the apiConnRoutineManager. Its purpose is to prevent errors related to shutting down from propagating to the manager's error group, which will tear down the API connection and potentially stop gracef
(ctx context.Context, logger slog.Logger, err error)
| 2498 | // apiConnRoutineManager. Its purpose is to prevent errors related to shutting down from propagating to the manager's |
| 2499 | // error group, which will tear down the API connection and potentially stop graceful shutdown from succeeding. |
| 2500 | func shouldPropagateError(ctx context.Context, logger slog.Logger, err error) error { |
| 2501 | if (xerrors.Is(err, context.Canceled) || |
| 2502 | xerrors.Is(err, io.EOF)) && |
| 2503 | ctx.Err() != nil { |
| 2504 | logger.Debug(ctx, "swallowing error because context is canceled", slog.Error(err)) |
| 2505 | // Don't propagate context canceled errors to the error group, because we don't want the |
| 2506 | // graceful context being canceled to halt the work of routines with |
| 2507 | // gracefulShutdownBehaviorRemain. Unfortunately, the dRPC library closes the stream |
| 2508 | // when context is canceled on an RPC, so canceling the context can also show up as |
| 2509 | // io.EOF. Also, when Coderd unilaterally closes the API connection (for example if the |
| 2510 | // build is outdated), it can sometimes show up as context.Canceled in our RPC calls. |
| 2511 | // We can't reliably distinguish between a context cancelation and a legit EOF, so we |
| 2512 | // also check that *our* context is currently canceled. If it is, we can safely ignore |
| 2513 | // the error. |
| 2514 | return nil |
| 2515 | } |
| 2516 | if xerrors.Is(err, ErrAgentClosing) { |
| 2517 | logger.Debug(ctx, "swallowing error because agent is closing") |
| 2518 | // This can only be generated when the agent is closing, so we never want it to propagate to other routines. |
| 2519 | // (They are signaled to exit via canceled contexts.) |
| 2520 | return nil |
| 2521 | } |
| 2522 | return err |
| 2523 | } |
| 2524 | |
| 2525 | func (a *apiConnRoutineManager) wait() error { |
| 2526 | return a.eg.Wait() |
no test coverage detected