force UI teardown when event is sourced from a signal interrupt (#453)

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman 2021-06-29 18:16:32 -04:00 committed by GitHub
parent fb0857ff93
commit 2de56c0749
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 14 additions and 10 deletions

View File

@ -13,7 +13,7 @@ import (
// eventLoop listens to worker errors (from execution path), worker events (from a partybus subscription), and // eventLoop listens to worker errors (from execution path), worker events (from a partybus subscription), and
// signal interrupts. Is responsible for handling each event relative to a given UI an to coordinate eventing until // signal interrupts. Is responsible for handling each event relative to a given UI an to coordinate eventing until
// an eventual graceful exit. // an eventual graceful exit.
// nolint:gocognit // nolint:gocognit,funlen
func eventLoop(workerErrs <-chan error, signals <-chan os.Signal, subscription *partybus.Subscription, ux ui.UI, cleanupFn func()) error { func eventLoop(workerErrs <-chan error, signals <-chan os.Signal, subscription *partybus.Subscription, ux ui.UI, cleanupFn func()) error {
defer cleanupFn() defer cleanupFn()
events := subscription.Events() events := subscription.Events()
@ -23,6 +23,7 @@ func eventLoop(workerErrs <-chan error, signals <-chan os.Signal, subscription *
} }
var retErr error var retErr error
var forceTeardown bool
for { for {
if workerErrs == nil && events == nil { if workerErrs == nil && events == nil {
@ -66,10 +67,11 @@ func eventLoop(workerErrs <-chan error, signals <-chan os.Signal, subscription *
// of processing. // of processing.
events = nil events = nil
workerErrs = nil workerErrs = nil
forceTeardown = true
} }
} }
if err := ux.Teardown(); err != nil { if err := ux.Teardown(forceTeardown); err != nil {
retErr = multierror.Append(retErr, err) retErr = multierror.Append(retErr, err)
} }

View File

@ -37,7 +37,7 @@ func (u *uiMock) Handle(event partybus.Event) error {
return u.Called(event).Error(0) return u.Called(event).Error(0)
} }
func (u *uiMock) Teardown() error { func (u *uiMock) Teardown(_ bool) error {
u.t.Logf("UI Teardown called") u.t.Logf("UI Teardown called")
return u.Called().Error(0) return u.Called().Error(0)
} }

View File

@ -77,7 +77,7 @@ func (h *ephemeralTerminalUI) Handle(event partybus.Event) error {
case event.Type == syftEvent.PresenterReady: case event.Type == syftEvent.PresenterReady:
// we need to close the screen now since signaling the the presenter is ready means that we // we need to close the screen now since signaling the the presenter is ready means that we
// are about to write bytes to stdout, so we should reset the terminal state first // are about to write bytes to stdout, so we should reset the terminal state first
h.closeScreen() h.closeScreen(false)
if err := handleCatalogerPresenterReady(event); err != nil { if err := handleCatalogerPresenterReady(event); err != nil {
log.Errorf("unable to show %s event: %+v", event.Type, err) log.Errorf("unable to show %s event: %+v", event.Type, err)
@ -105,11 +105,13 @@ func (h *ephemeralTerminalUI) openScreen() error {
return nil return nil
} }
func (h *ephemeralTerminalUI) closeScreen() { func (h *ephemeralTerminalUI) closeScreen(force bool) {
// we may have other background processes still displaying progress, wait for them to // we may have other background processes still displaying progress, wait for them to
// finish before discontinuing dynamic content and showing the final report // finish before discontinuing dynamic content and showing the final report
if !h.frame.IsClosed() { if !h.frame.IsClosed() {
h.waitGroup.Wait() if !force {
h.waitGroup.Wait()
}
h.frame.Close() h.frame.Close()
// TODO: there is a race condition within frame.Close() that sometimes leads to an extra blank line being output // TODO: there is a race condition within frame.Close() that sometimes leads to an extra blank line being output
frame.Close() frame.Close()
@ -130,8 +132,8 @@ func (h *ephemeralTerminalUI) flushLog() {
} }
} }
func (h *ephemeralTerminalUI) Teardown() error { func (h *ephemeralTerminalUI) Teardown(force bool) error {
h.closeScreen() h.closeScreen(force)
ansi.CursorShow() ansi.CursorShow()
return nil return nil
} }

View File

@ -33,6 +33,6 @@ func (l loggerUI) Handle(event partybus.Event) error {
return l.unsubscribe() return l.unsubscribe()
} }
func (l loggerUI) Teardown() error { func (l loggerUI) Teardown(_ bool) error {
return nil return nil
} }

View File

@ -7,5 +7,5 @@ import (
type UI interface { type UI interface {
Setup(unsubscribe func() error) error Setup(unsubscribe func() error) error
partybus.Handler partybus.Handler
Teardown() error Teardown(force bool) error
} }