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

Function watchAndClose

cli/ssh.go:940–997  ·  view source on GitHub ↗

watchAndClose ensures closer is called if the context is canceled or the workspace reaches the stopped state. Watching the stopped state is a work-around for cases where the agent is not gracefully shut down and the connection is left open. If, for instance, the networking is stopped before the age

(ctx context.Context, closer func() error, logger slog.Logger, client *codersdk.Client, workspace codersdk.Workspace, errCh <-chan error)

Source from the content-addressed store, hash-verified

938//
939// See: https://github.com/coder/coder/issues/6180
940func watchAndClose(ctx context.Context, closer func() error, logger slog.Logger, client *codersdk.Client, workspace codersdk.Workspace, errCh <-chan error) {
941 // Ensure session is ended on both context cancellation
942 // and workspace stop.
943 defer func() {
944 err := closer()
945 if err != nil {
946 logger.Error(ctx, "error closing session", slog.Error(err))
947 }
948 }()
949
950startWatchLoop:
951 for {
952 logger.Debug(ctx, "connecting to the coder server to watch workspace events")
953 var wsWatch <-chan codersdk.Workspace
954 var err error
955 for r := retry.New(time.Second, 15*time.Second); r.Wait(ctx); {
956 wsWatch, err = client.WatchWorkspace(ctx, workspace.ID)
957 if err == nil {
958 break
959 }
960 if ctx.Err() != nil {
961 logger.Debug(ctx, "context expired", slog.Error(ctx.Err()))
962 return
963 }
964 }
965
966 for {
967 select {
968 case <-ctx.Done():
969 logger.Debug(ctx, "context expired", slog.Error(ctx.Err()))
970 return
971 case w, ok := <-wsWatch:
972 if !ok {
973 continue startWatchLoop
974 }
975
976 // Transitioning to stop or delete could mean that
977 // the agent will still gracefully stop. If a new
978 // build is starting, there's no reason to wait for
979 // the agent, it should be long gone.
980 if workspace.LatestBuild.ID != w.LatestBuild.ID && w.LatestBuild.Transition == codersdk.WorkspaceTransitionStart {
981 logger.Info(ctx, "new build started")
982 return
983 }
984 // Note, we only react to the stopped state here because we
985 // want to give the agent a chance to gracefully shut down
986 // during "stopping".
987 if w.LatestBuild.Status == codersdk.WorkspaceStatusStopped {
988 logger.Info(ctx, "workspace stopped")
989 return
990 }
991 case err := <-errCh:
992 logger.Error(ctx, "failed to collect network stats", slog.Error(err))
993 return
994 }
995 }
996 }
997}

Callers 1

sshMethod · 0.85

Calls 7

WatchWorkspaceMethod · 0.80
ErrMethod · 0.80
NewMethod · 0.65
WaitMethod · 0.65
ErrorMethod · 0.45
DoneMethod · 0.45
InfoMethod · 0.45

Tested by

no test coverage detected