@@ -3,7 +3,6 @@ package cli
33import (
44 "context"
55 "crypto/tls"
6- "errors"
76 "fmt"
87 "io/fs"
98 "log"
@@ -37,23 +36,15 @@ type apiOptions struct {
3736 WebAssetsFS fs.FS
3837}
3938
40- func startAPI (ctx context.Context , cert tls.Certificate , opts apiOptions , cancel context.CancelFunc ) error {
39+ // startAPI starts the API server and returns a channel that will receive an error if the API exits unexpectedly.
40+ // The returned channel will be closed when the API exits normally (via context cancellation).
41+ func startAPI (ctx context.Context , cert tls.Certificate , opts apiOptions ) (<- chan error , error ) {
4142 listener , err := net .Listen ("tcp" , fmt .Sprintf (":%d" , opts .ManagerPort ))
4243 if err != nil {
43- return fmt .Errorf ("unable to create listener: %w" , err )
44+ return nil , fmt .Errorf ("unable to create listener: %w" , err )
4445 }
4546 logrus .Debugf ("API server listening on port: %d" , opts .ManagerPort )
4647
47- go func () {
48- // If the api exits, we want to exit the entire process
49- defer cancel ()
50- if err := serveAPI (ctx , listener , cert , opts ); err != nil {
51- if ! errors .Is (err , http .ErrServerClosed ) {
52- logrus .Errorf ("API server exited with error: %v" , err )
53- }
54- }
55- }()
56-
5748 addr := fmt .Sprintf ("https://localhost:%d" , opts .ManagerPort )
5849 httpClient := & http.Client {
5950 Timeout : 2 * time .Second ,
@@ -64,11 +55,30 @@ func startAPI(ctx context.Context, cert tls.Certificate, opts apiOptions, cancel
6455 },
6556 },
6657 }
67- if err := waitForAPI (ctx , httpClient , addr ); err != nil {
68- return fmt .Errorf ("unable to wait for api: %w" , err )
58+
59+ apiExitCh := make (chan error , 1 )
60+ waitErrCh := make (chan error , 1 )
61+
62+ go func () {
63+ apiExitCh <- serveAPI (ctx , listener , cert , opts )
64+ }()
65+
66+ go func () {
67+ waitErrCh <- waitForAPI (ctx , httpClient , addr )
68+ }()
69+
70+ select {
71+ case err := <- apiExitCh :
72+ if err != nil {
73+ return nil , fmt .Errorf ("serve api: %w" , err )
74+ }
75+ case err := <- waitErrCh :
76+ if err != nil {
77+ return apiExitCh , fmt .Errorf ("wait for api: %w" , err )
78+ }
6979 }
7080
71- return nil
81+ return apiExitCh , nil
7282}
7383
7484func serveAPI (ctx context.Context , listener net.Listener , cert tls.Certificate , opts apiOptions ) error {
0 commit comments