fix(lifecycle): retain parent cancellation at every shutdown return
This commit is contained in:
1 parent
64c7e6b65d
commit
f4abb626c6
2 files changed
+90
-30
No files matched your search
@@ -238,7 +238,7 @@ func (a *App) Run(parent context.Context) error {
|
||||
if !ok {
|
||||
signals = nil
|
||||
} else if err := receiveSignal(sig); err != nil {
|
||||
return a.result(err)
|
||||
return a.result(parent, err)
|
||||
}
|
||||
continue
|
||||
default:
|
||||
@@ -246,7 +246,6 @@ func (a *App) Run(parent context.Context) error {
|
||||
|
||||
a.mu.Lock()
|
||||
if !a.stopping && parent.Err() != nil {
|
||||
a.errs = append(a.errs, parent.Err())
|
||||
a.stopLocked()
|
||||
parentDone = nil
|
||||
}
|
||||
@@ -288,7 +287,7 @@ func (a *App) Run(parent context.Context) error {
|
||||
|
||||
if stopping {
|
||||
if err := shutdown.Err(); err != nil {
|
||||
return a.result(err)
|
||||
return a.result(parent, err)
|
||||
}
|
||||
if setupDone == nil && teardownDone == nil {
|
||||
if teardownIndex >= 0 {
|
||||
@@ -297,7 +296,7 @@ func (a *App) Run(parent context.Context) error {
|
||||
teardownDone = result
|
||||
go func() { result <- m.Teardown(shutdown) }()
|
||||
} else if active == 0 {
|
||||
return a.result(nil)
|
||||
return a.result(parent, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -325,7 +324,6 @@ func (a *App) Run(parent context.Context) error {
|
||||
case <-a.wake:
|
||||
case <-parentDone:
|
||||
a.mu.Lock()
|
||||
a.errs = append(a.errs, parent.Err())
|
||||
a.stopLocked()
|
||||
a.mu.Unlock()
|
||||
parentDone = nil
|
||||
@@ -335,16 +333,17 @@ func (a *App) Run(parent context.Context) error {
|
||||
continue
|
||||
}
|
||||
if err := receiveSignal(sig); err != nil {
|
||||
return a.result(err)
|
||||
return a.result(parent, err)
|
||||
}
|
||||
case <-deadline:
|
||||
return a.result(context.DeadlineExceeded)
|
||||
return a.result(parent, context.DeadlineExceeded)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) result(extra error) error {
|
||||
func (a *App) result(parent context.Context, extra error) error {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
return errors.Join(append(a.errs, extra)...)
|
||||
// invariant: every completion and abandonment retains parent cancellation exactly once.
|
||||
return errors.Join(append(a.errs, parent.Err(), extra)...)
|
||||
}
|
||||
Reference in new issue
Block a user