MCPcopy Create free account
hub / github.com/Shopify/goose / Wait

Method Wait

shell/supervisor.go:54–105  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

52}
53
54func (w *wrapper) Wait() (err error) {
55 defer metrics.ShellCommandRun.StartTimer(w.ctx).SuccessFinish(&err)
56
57 cmd := w.cmd
58
59 if w.ctx == nil || !w.ctxCancellation {
60 return cmd.Wait()
61 }
62
63 done := make(chan error, 1)
64
65 go func() {
66 err := cmd.Wait()
67 if atomic.LoadUint32(&w.killedByCancel) > 0 {
68 // Normally, the cmd would report it was "terminated".
69 // In reality, the context was canceled and we gracefully stopped it, report as such.
70 err = w.ctx.Err()
71 }
72 done <- err
73 }()
74
75 select {
76 case err := <-done:
77 return err
78 case <-w.ctx.Done():
79 log(w.ctx, nil).Info("command was canceled; attempting graceful termination")
80
81 atomic.AddUint32(&w.killedByCancel, 1)
82 err := w.killIgnoreDead(syscall.SIGTERM)
83 if err != nil {
84 log(w.ctx, err).Warn("unable to sigterm process; attempting killing")
85 atomic.AddUint32(&w.killedByCancel, 1)
86 if err := w.killIgnoreDead(syscall.SIGKILL); err != nil {
87 return errors.Wrap(err, "unable to kill process")
88 }
89
90 return <-done
91 }
92
93 select {
94 case err := <-done:
95 return err
96 case <-time.After(w.gracefulTerminationOnCancelTimeout):
97 log(w.ctx, nil).Warn("command was canceled and did not terminate in time; killing")
98 atomic.AddUint32(&w.killedByCancel, 1)
99 if err := w.killIgnoreDead(syscall.SIGKILL); err != nil {
100 return errors.Wrap(err, "unable to kill process")
101 }
102 return <-done
103 }
104 }
105}
106
107func (w *wrapper) killIgnoreDead(signal syscall.Signal) error {
108 err := w.Kill(signal)

Callers 1

RunMethod · 0.95

Calls 4

killIgnoreDeadMethod · 0.95
StartTimerMethod · 0.80
SuccessFinishMethod · 0.65
WaitMethod · 0.65

Tested by

no test coverage detected