From 22447b9588b009d1c6e3e9cbbf34ae4a05f17e9f Mon Sep 17 00:00:00 2001 From: Mihail Stoykov Date: Wed, 4 Nov 2020 11:40:05 +0200 Subject: [PATCH] wait for cloud to actually stop the test on first '^C' (#1705) Also: - move the signal handling as far up as possible - stop the test in goroutine so if that takes a while a second ^C will again stop the test Co-authored-by: na-- --- cmd/cloud.go | 75 ++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/cmd/cloud.go b/cmd/cloud.go index 8f82aaad3b9a..3ef790fe80c0 100644 --- a/cmd/cloud.go +++ b/cmd/cloud.go @@ -213,6 +213,29 @@ This will execute the test on the k6 cloud service. Use "k6 login cloud" to auth return err } + // Trap Interrupts, SIGINTs and SIGTERMs. + sigC := make(chan os.Signal, 1) + signal.Notify(sigC, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + defer signal.Stop(sigC) + go func() { + sig := <-sigC + logger.WithField("sig", sig).Print("Stopping cloud test run in response to signal...") + // Do this in a separate goroutine so that if it blocks the second signal can stop the execution + go func() { + stopErr := client.StopCloudTestRun(refID) + if stopErr != nil { + logger.WithError(stopErr).Error("Stop cloud test error") + } else { + logger.Info("Successfully sent signal to stop the cloud test, now waiting for it to actually stop...") + } + globalCancel() + }() + + sig = <-sigC + logger.WithField("sig", sig).Error("Aborting k6 in response to signal, we won't wait for the test to end.") + os.Exit(externalAbortErrorCode) + }() + et, err := lib.NewExecutionTuple(derivedConf.ExecutionSegment, derivedConf.ExecutionSegmentSequence) if err != nil { return err @@ -237,24 +260,6 @@ This will execute the test on the k6 cloud service. Use "k6 login cloud" to auth progressBarWG.Done() }() - // Trap Interrupts, SIGINTs and SIGTERMs. - sigC := make(chan os.Signal, 1) - signal.Notify(sigC, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - defer signal.Stop(sigC) - go func() { - sig := <-sigC - logger.WithField("sig", sig).Print("Stopping k6 in response to signal...") - err := client.StopCloudTestRun(refID) - if err != nil { - logger.WithError(err).Error("Stop cloud test error") - } - globalCancel() - - sig = <-sigC - logger.WithField("sig", sig).Error("Aborting k6 in response to signal") - os.Exit(externalAbortErrorCode) - }() - var ( startTime time.Time maxDuration time.Duration @@ -302,25 +307,21 @@ This will execute the test on the k6 cloud service. Use "k6 login cloud" to auth }() } - runningLoop: - for { - select { - case <-ticker.C: - newTestProgress, progressErr := client.GetTestProgress(refID) - if progressErr == nil { - if (newTestProgress.RunStatus > lib.RunStatusRunning) || - (exitOnRunning && newTestProgress.RunStatus == lib.RunStatusRunning) { - globalCancel() - break runningLoop - } - testProgressLock.Lock() - testProgress = newTestProgress - testProgressLock.Unlock() - } else { - logger.WithError(progressErr).Error("Test progress error") - } - case <-globalCtx.Done(): - break runningLoop + for range ticker.C { + newTestProgress, progressErr := client.GetTestProgress(refID) + if progressErr != nil { + logger.WithError(progressErr).Error("Test progress error") + continue + } + + testProgressLock.Lock() + testProgress = newTestProgress + testProgressLock.Unlock() + + if (newTestProgress.RunStatus > lib.RunStatusRunning) || + (exitOnRunning && newTestProgress.RunStatus == lib.RunStatusRunning) { + globalCancel() + break } }