From 2de56c074917b159fdd76fc6b1da974b4c53ca2e Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Tue, 29 Jun 2021 18:16:32 -0400 Subject: [PATCH] force UI teardown when event is sourced from a signal interrupt (#453) Signed-off-by: Alex Goodman --- cmd/event_loop.go | 6 ++++-- cmd/event_loop_test.go | 2 +- internal/ui/ephemeral_terminal_ui.go | 12 +++++++----- internal/ui/logger_ui.go | 2 +- internal/ui/ui.go | 2 +- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/cmd/event_loop.go b/cmd/event_loop.go index 0c7518942e97..72cddb9718e7 100644 --- a/cmd/event_loop.go +++ b/cmd/event_loop.go @@ -13,7 +13,7 @@ import ( // 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 // 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 { defer cleanupFn() events := subscription.Events() @@ -23,6 +23,7 @@ func eventLoop(workerErrs <-chan error, signals <-chan os.Signal, subscription * } var retErr error + var forceTeardown bool for { if workerErrs == nil && events == nil { @@ -66,10 +67,11 @@ func eventLoop(workerErrs <-chan error, signals <-chan os.Signal, subscription * // of processing. events = nil workerErrs = nil + forceTeardown = true } } - if err := ux.Teardown(); err != nil { + if err := ux.Teardown(forceTeardown); err != nil { retErr = multierror.Append(retErr, err) } diff --git a/cmd/event_loop_test.go b/cmd/event_loop_test.go index aa69ec73f02c..f1c962221768 100644 --- a/cmd/event_loop_test.go +++ b/cmd/event_loop_test.go @@ -37,7 +37,7 @@ func (u *uiMock) Handle(event partybus.Event) error { return u.Called(event).Error(0) } -func (u *uiMock) Teardown() error { +func (u *uiMock) Teardown(_ bool) error { u.t.Logf("UI Teardown called") return u.Called().Error(0) } diff --git a/internal/ui/ephemeral_terminal_ui.go b/internal/ui/ephemeral_terminal_ui.go index 3684fdeb09c5..a37e25336931 100644 --- a/internal/ui/ephemeral_terminal_ui.go +++ b/internal/ui/ephemeral_terminal_ui.go @@ -77,7 +77,7 @@ func (h *ephemeralTerminalUI) Handle(event partybus.Event) error { case event.Type == syftEvent.PresenterReady: // 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 - h.closeScreen() + h.closeScreen(false) if err := handleCatalogerPresenterReady(event); err != nil { log.Errorf("unable to show %s event: %+v", event.Type, err) @@ -105,11 +105,13 @@ func (h *ephemeralTerminalUI) openScreen() error { 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 // finish before discontinuing dynamic content and showing the final report if !h.frame.IsClosed() { - h.waitGroup.Wait() + if !force { + h.waitGroup.Wait() + } h.frame.Close() // TODO: there is a race condition within frame.Close() that sometimes leads to an extra blank line being output frame.Close() @@ -130,8 +132,8 @@ func (h *ephemeralTerminalUI) flushLog() { } } -func (h *ephemeralTerminalUI) Teardown() error { - h.closeScreen() +func (h *ephemeralTerminalUI) Teardown(force bool) error { + h.closeScreen(force) ansi.CursorShow() return nil } diff --git a/internal/ui/logger_ui.go b/internal/ui/logger_ui.go index ae2c59d12235..7108711b9bdc 100644 --- a/internal/ui/logger_ui.go +++ b/internal/ui/logger_ui.go @@ -33,6 +33,6 @@ func (l loggerUI) Handle(event partybus.Event) error { return l.unsubscribe() } -func (l loggerUI) Teardown() error { +func (l loggerUI) Teardown(_ bool) error { return nil } diff --git a/internal/ui/ui.go b/internal/ui/ui.go index 5e41b400fcb3..cb551f1cfcbb 100644 --- a/internal/ui/ui.go +++ b/internal/ui/ui.go @@ -7,5 +7,5 @@ import ( type UI interface { Setup(unsubscribe func() error) error partybus.Handler - Teardown() error + Teardown(force bool) error }