From 641af0a002dedc756fae6814d0b4dc739a4dd529 Mon Sep 17 00:00:00 2001 From: ka3de Date: Mon, 6 Nov 2023 15:53:27 +0100 Subject: [PATCH] Stop tracer provider from root command Waits for tracer provider to stop within 5 seconds, otherwise an error message is logged. Because both methods, stopLoggers() and stopTracerProvider(), are bounded by a timeout, execute them concurrently and wait for them to finish. --- cmd/root.go | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index edf588c7ad5..f51f3d2dd32 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -24,7 +24,10 @@ import ( "go.k6.io/k6/log" ) -const waitLoggerCloseTimeout = time.Second * 5 +const ( + waitLoggerCloseTimeout = time.Second * 5 + waitForTracerProviderStopTimeout = time.Second * 5 +) // This is to keep all fields needed for the main/root k6 command type rootCommand struct { @@ -97,7 +100,21 @@ func (c *rootCommand) execute() { exitCode := -1 defer func() { cancel() - c.stopLoggers() + + // Wait for loggers and tracer provider to stop. + // As both methods already use a timeout, just wait. + var wg sync.WaitGroup + ff := [...]func(){c.stopLoggers, c.stopTracerProvider} + wg.Add(len(ff)) + for _, f := range ff { + f := f + go func() { + f() + wg.Done() + }() + } + wg.Wait() + c.globalState.OSExit(exitCode) }() @@ -158,6 +175,17 @@ func (c *rootCommand) stopLoggers() { } } +func (c *rootCommand) stopTracerProvider() { + ctx, cancel := context.WithTimeout(context.Background(), waitForTracerProviderStopTimeout) + defer cancel() + + if err := c.globalState.TracerProvider.Shutdown(ctx); err != nil { + c.globalState.FallbackLogger.Errorf( + "The tracer provider didn't stop gracefully: %v", err, + ) + } +} + func rootCmdPersistentFlagSet(gs *state.GlobalState) *pflag.FlagSet { flags := pflag.NewFlagSet("", pflag.ContinueOnError) // TODO: refactor this config, the default value management with pflag is