...
1
16
17 package manager
18
19 import (
20 "context"
21 "errors"
22 "net"
23 "net/http"
24 "time"
25
26 crlog "sigs.k8s.io/controller-runtime/pkg/log"
27 )
28
29 var (
30 _ Runnable = (*Server)(nil)
31 _ LeaderElectionRunnable = (*Server)(nil)
32 )
33
34
35
36
37 type Server struct {
38
39
40 Name string
41
42
43 Server *http.Server
44
45
46
47 Listener net.Listener
48
49
50 OnlyServeWhenLeader bool
51
52
53
54 ShutdownTimeout *time.Duration
55 }
56
57
58 func (s *Server) Start(ctx context.Context) error {
59 log := crlog.FromContext(ctx)
60 if s.Name != "" {
61 log = log.WithValues("name", s.Name)
62 }
63 log = log.WithValues("addr", s.addr())
64
65 serverShutdown := make(chan struct{})
66 go func() {
67 <-ctx.Done()
68 log.Info("shutting down server")
69
70 shutdownCtx := context.Background()
71 if s.ShutdownTimeout != nil {
72 var shutdownCancel context.CancelFunc
73 shutdownCtx, shutdownCancel = context.WithTimeout(context.Background(), *s.ShutdownTimeout)
74 defer shutdownCancel()
75 }
76
77 if err := s.Server.Shutdown(shutdownCtx); err != nil {
78 log.Error(err, "error shutting down server")
79 }
80 close(serverShutdown)
81 }()
82
83 log.Info("starting server")
84 if err := s.serve(); err != nil && !errors.Is(err, http.ErrServerClosed) {
85 return err
86 }
87
88 <-serverShutdown
89 return nil
90 }
91
92
93 func (s *Server) NeedLeaderElection() bool {
94 return s.OnlyServeWhenLeader
95 }
96
97 func (s *Server) addr() string {
98 if s.Listener != nil {
99 return s.Listener.Addr().String()
100 }
101 return s.Server.Addr
102 }
103
104 func (s *Server) serve() error {
105 if s.Listener != nil {
106 return s.Server.Serve(s.Listener)
107 }
108 return s.Server.ListenAndServe()
109 }
110
View as plain text