Skip to content

Commit 296359b

Browse files
committed
Stop the server when the context is cancelled
Signed-off-by: Richard Wall <[email protected]>
1 parent c87f7c3 commit 296359b

File tree

1 file changed

+60
-12
lines changed

1 file changed

+60
-12
lines changed

pkg/agent/run.go

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"k8s.io/client-go/kubernetes"
2626
clientgocorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
2727
"k8s.io/client-go/tools/record"
28+
"k8s.io/klog/v2"
2829
"sigs.k8s.io/controller-runtime/pkg/manager"
2930

3031
"github.com/jetstack/preflight/api"
@@ -50,7 +51,12 @@ const schemaVersion string = "v2.0.0"
5051
// Run starts the agent process
5152
func Run(cmd *cobra.Command, args []string) {
5253
logs.Log.Printf("Preflight agent version: %s (%s)", version.PreflightVersion, version.Commit)
53-
ctx, cancel := context.WithCancel(context.Background())
54+
ctx, cancel := context.WithCancel(
55+
klog.NewContext(
56+
context.Background(),
57+
klog.Background(),
58+
),
59+
)
5460
defer cancel()
5561

5662
file, err := os.Open(Flags.ConfigFilePath)
@@ -83,11 +89,13 @@ func Run(cmd *cobra.Command, args []string) {
8389
}
8490
}()
8591

86-
group.Go(func() error {
92+
{
8793
server := http.NewServeMux()
94+
const serverAddress = ":8081"
95+
log := klog.FromContext(ctx).WithName("APIServer").WithValues("addr", serverAddress)
8896

8997
if Flags.Profiling {
90-
logs.Log.Printf("pprof profiling was enabled.")
98+
log.Info("Profiling endpoints enabled", "path", "/debug/pprof")
9199
server.HandleFunc("/debug/pprof/", pprof.Index)
92100
server.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
93101
server.HandleFunc("/debug/pprof/profile", pprof.Profile)
@@ -96,7 +104,7 @@ func Run(cmd *cobra.Command, args []string) {
96104
}
97105

98106
if Flags.Prometheus {
99-
logs.Log.Printf("Prometheus was enabled.\nRunning prometheus on port :8081")
107+
log.Info("Metrics endpoints enabled", "path", "/metrics")
100108
prometheus.MustRegister(metricPayloadSize)
101109
server.Handle("/metrics", promhttp.Handler())
102110
}
@@ -105,21 +113,23 @@ func Run(cmd *cobra.Command, args []string) {
105113
// what "ready" means for the agent, we just return 200 OK inconditionally.
106114
// The goal is to satisfy some Kubernetes distributions, like OpenShift,
107115
// that require a liveness and health probe to be present for each pod.
116+
log.Info("Healthz endpoints enabled", "path", "/healthz")
108117
server.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
109118
w.WriteHeader(http.StatusOK)
110119
})
120+
log.Info("Readyz endpoints enabled", "path", "/readyz")
111121
server.HandleFunc("/readyz", func(w http.ResponseWriter, r *http.Request) {
112122
w.WriteHeader(http.StatusOK)
113123
})
114124

115-
err := http.ListenAndServe(":8081", server)
116-
if err != nil && !errors.Is(err, http.ErrServerClosed) {
117-
return fmt.Errorf("failed to run the health check server: %s", err)
118-
}
119-
// The agent must stop if the management server stops
120-
cancel()
121-
return nil
122-
})
125+
group.Go(func() error {
126+
return listenAndServe(
127+
klog.NewContext(gctx, log),
128+
serverAddress,
129+
server,
130+
)
131+
})
132+
}
123133

124134
_, isVenConn := preflightClient.(*client.VenConnClient)
125135
if isVenConn {
@@ -412,3 +422,41 @@ func postData(config CombinedConfig, preflightClient client.Client, readings []*
412422

413423
return nil
414424
}
425+
426+
// listenAndServe starts an HTTP server at the given addr with the given handler
427+
// and stops it gracefully when the supplied context is cancelled.
428+
// It returns when the graceful server shutdown is complete or when the server
429+
// exits with an error.
430+
// If the server fails to start, it returns the server error.
431+
// If the server fails to shutdown gracefully, it returns the shutdown error.
432+
// The server is given 1s to shutdown gracefully before it is stopped
433+
// forcefully.
434+
func listenAndServe(ctx context.Context, addr string, handler http.Handler) error {
435+
log := klog.FromContext(ctx).WithName("ListenAndServe")
436+
server := &http.Server{Addr: addr, Handler: handler}
437+
group, gCTX := errgroup.WithContext(ctx)
438+
group.Go(func() error {
439+
log.V(1).Info("Starting")
440+
err := server.ListenAndServe()
441+
log.V(1).Info("Stopped", "reason", err)
442+
if errors.Is(err, http.ErrServerClosed) {
443+
err = nil
444+
}
445+
return err
446+
})
447+
group.Go(func() error {
448+
select {
449+
case <-ctx.Done():
450+
log.V(1).Info("Shutting down")
451+
shutdownCTX, cancel := context.WithTimeout(context.Background(), time.Second)
452+
defer cancel()
453+
err := server.Shutdown(shutdownCTX)
454+
log.V(1).Info("Shutdown complete", "err", err)
455+
return err
456+
case <-gCTX.Done():
457+
log.V(1).Info("Shutdown skipped", "addr", addr, "reason", "Server already stopped")
458+
return nil
459+
}
460+
})
461+
return group.Wait()
462+
}

0 commit comments

Comments
 (0)