@@ -58,11 +58,11 @@ const (
5858// serve starts the REST API server and ensures it is properly shut down when
5959// the srvCtx is done. It returns a function that can be waited on to ensure
6060// the server has fully stopped.
61- //
62- // nolint:nestif
63- func (c * cmdRun ) serve (cmd * cobra.Command , srv * http.Server , shutdown func ()) func () {
61+ func (c * cmdRun ) serve (globalCtx context.Context , srv * http.Server , addrSetByUser bool ) func () {
6462 var logger logrus.FieldLogger = c .gs .Logger
6563
64+ srvCtx , srvCancel := context .WithCancel (globalCtx )
65+
6666 // We cannot use backgroundProcesses here, since we need the REST API to
6767 // be down before we can close the samples channel above and finish the
6868 // processing the metrics pipeline.
@@ -79,30 +79,42 @@ func (c *cmdRun) serve(cmd *cobra.Command, srv *http.Server, shutdown func()) fu
7979 // ServerListener is set up in tests
8080 if c .gs .ServerListener != nil {
8181 if err := srv .Serve (c .gs .ServerListener ); err != nil && ! errors .Is (err , http .ErrServerClosed ) {
82- logger .WithError (err ).Error ("Error from API server" )
83- c .gs .OSExit (int (exitcodes .CannotStartRESTAPI ))
82+ if addrSetByUser {
83+ logger .WithError (err ).Error ("Error from API server" )
84+ c .gs .OSExit (int (exitcodes .CannotStartRESTAPI ))
85+ } else {
86+ logger .WithError (err ).Warn ("Error from API server" )
87+ }
8488 }
8589 return
8690 }
87-
88- if err := srv .ListenAndServe (); err != nil && ! errors .Is (err , http .ErrServerClosed ) {
91+
92+ if err := srv .ListenAndServe (); err != nil && ! errors .Is (err , http .ErrServerClosed ) {
8993 // Only exit k6 if the user has explicitly set the REST API address
90- if cmd . Flags (). Lookup ( "address" ). Changed {
94+ if addrSetByUser {
9195 logger .WithError (err ).Error ("Error from API server" )
9296 c .gs .OSExit (int (exitcodes .CannotStartRESTAPI ))
9397 } else {
9498 logger .WithError (err ).Warn ("Error from API server" )
9599 }
96100 }
97- }
98101 }()
99102
100103 go func () {
101104 defer apiWG .Done ()
102- shutdown ()
105+ <- srvCtx .Done ()
106+ shutdCtx , shutdCancel := context .WithTimeout (globalCtx , 1 * time .Second )
107+ defer shutdCancel ()
108+ if aerr := srv .Shutdown (shutdCtx ); aerr != nil {
109+ logger .WithError (aerr ).Debug ("REST API server did not shut down correctly" )
110+ }
103111 }()
104112
105- return apiWG .Wait
113+ return func () {
114+ // Cancel the server context before shutdown to avoid the deadlocks
115+ srvCancel ()
116+ apiWG .Wait ()
117+ }
106118}
107119
108120// TODO: split apart some more
@@ -342,8 +354,6 @@ func (c *cmdRun) run(cmd *cobra.Command, args []string) (err error) {
342354 if c .gs .Flags .Address != "" {
343355 initBar .Modify (pb .WithConstProgress (0 , "Init API server" ))
344356
345- srvCtx , srvCancel := context .WithCancel (globalCtx )
346-
347357 srv := api .GetServer (
348358 runCtx ,
349359 c .gs .Flags .Address , c .gs .Flags .ProfilingEnabled ,
@@ -352,20 +362,8 @@ func (c *cmdRun) run(cmd *cobra.Command, args []string) (err error) {
352362 metricsEngine ,
353363 execScheduler ,
354364 )
355- shutdown := func () {
356- <- srvCtx .Done ()
357- shutdCtx , shutdCancel := context .WithTimeout (globalCtx , 1 * time .Second )
358- defer shutdCancel ()
359- if aerr := srv .Shutdown (shutdCtx ); aerr != nil {
360- logger .WithError (aerr ).Debug ("REST API server did not shut down correctly" )
361- }
362- }
363- srvWait := c .serve (cmd , srv , shutdown )
364- defer func () {
365- // Cancel the server context before shutdown to avoid the deadlocks
366- srvCancel ()
367- srvWait ()
368- }()
365+ srvWait := c .serve (globalCtx , srv , cmd .Flags ().Lookup ("address" ).Changed )
366+ defer srvWait ()
369367 }
370368
371369 waitOutputsFlushed , stopOutputs , err := outputManager .Start (samples )
0 commit comments