@@ -9,18 +9,20 @@ import (
99 "strconv"
1010 "time"
1111
12+ "github.com/rs/zerolog/log"
13+
1214 "github.com/onflow/flow-go/module/component"
1315 "github.com/onflow/flow-go/module/irrecoverable"
1416
1517 "github.com/rs/zerolog"
1618)
1719
1820type ProfileServer struct {
21+ component.Component
22+
1923 log zerolog.Logger
2024 server * http.Server
2125 endpoint string
22-
23- startupCompleted chan struct {}
2426}
2527
2628var _ component.Component = (* ProfileServer )(nil )
@@ -31,70 +33,69 @@ func NewProfileServer(
3133 port int ,
3234) * ProfileServer {
3335 endpoint := net .JoinHostPort (host , strconv .Itoa (port ))
34- return & ProfileServer {
35- log : logger ,
36- server : & http. Server { Addr : endpoint } ,
37- endpoint : endpoint ,
38- startupCompleted : make ( chan struct {}) ,
36+
37+ s := & ProfileServer {
38+ log : logger ,
39+ server : & http. Server { Addr : endpoint } ,
40+ endpoint : endpoint ,
3941 }
42+
43+ s .Component = component .NewComponentManagerBuilder ().
44+ AddWorker (s .serve ).
45+ AddWorker (s .shutdownOnContextDone ).
46+ Build ()
47+
48+ return s
4049}
4150
42- func (s * ProfileServer ) Start (ctx irrecoverable.SignalerContext ) {
43- defer close (s .startupCompleted )
51+ func (s * ProfileServer ) serve (ctx irrecoverable.SignalerContext , ready component.ReadyFunc ) {
52+ s .log .Info ().Msg ("starting profiler server on address" )
53+
54+ l , err := net .Listen ("tcp" , s .endpoint )
55+ if err != nil {
56+ s .log .Err (err ).Msg ("failed to start the metrics server" )
57+ ctx .Throw (err )
58+ return
59+ }
60+
61+ ready ()
4462
63+ // pass the signaler context to the server so that the signaler context
64+ // can control the server's lifetime
4565 s .server .BaseContext = func (_ net.Listener ) context.Context {
4666 return ctx
4767 }
4868
49- go func () {
50- s .log .Info ().Msgf ("Profiler server started: %s" , s .endpoint )
51-
52- if err := s .server .ListenAndServe (); err != nil {
53- // http.ErrServerClosed is returned when Close or Shutdown is called
54- // we don't consider this an error, so print this with debug level instead
55- if errors .Is (err , http .ErrServerClosed ) {
56- s .log .Debug ().Err (err ).Msg ("Profiler server shutdown" )
57- } else {
58- s .log .Err (err ).Msg ("error running profiler server" )
59- }
69+ err = s .server .Serve (l ) // blocking call
70+ if err != nil {
71+ if errors .Is (err , http .ErrServerClosed ) {
72+ return
6073 }
61- }()
62- }
63-
64- func (s * ProfileServer ) Ready () <- chan struct {} {
65- ready := make (chan struct {})
66-
67- go func () {
68- <- s .startupCompleted
69- close (ready )
70- }()
7174
72- return ready
75+ log .Err (err ).Msg ("fatal error in the metrics server" )
76+ ctx .Throw (err )
77+ }
7378}
7479
75- func (s * ProfileServer ) Done () <- chan struct {} {
76- done := make (chan struct {})
77- go func () {
78- <- s .startupCompleted
79- defer close (done )
80+ func (s * ProfileServer ) shutdownOnContextDone (ictx irrecoverable.SignalerContext , ready component.ReadyFunc ) {
81+ ready ()
82+ <- ictx .Done ()
8083
81- ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
82- defer cancel ()
84+ ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
85+ defer cancel ()
8386
84- err := s .server .Shutdown (ctx )
85- if err == nil {
86- s .log .Info ().Msg ("Profiler server graceful shutdown completed" )
87- }
87+ err := s .server .Shutdown (ctx )
88+ if err == nil {
89+ s .log .Info ().Msg ("Profiler server graceful shutdown completed" )
90+ }
8891
89- if errors .Is (err , ctx .Err ()) {
90- s .log .Warn ().Msg ("Profiler server graceful shutdown timed out" )
91- err := s .server .Close ()
92- if err != nil {
93- s .log .Err (err ).Msg ("error closing profiler server" )
94- }
95- } else {
96- s .log .Err (err ).Msg ("error shutting down profiler server" )
92+ if errors .Is (err , ctx .Err ()) {
93+ s .log .Warn ().Msg ("Profiler server graceful shutdown timed out" )
94+ err := s .server .Close ()
95+ if err != nil {
96+ s .log .Err (err ).Msg ("error closing profiler server" )
9797 }
98- }()
99- return done
98+ } else {
99+ s .log .Err (err ).Msg ("error shutting down profiler server" )
100+ }
100101}
0 commit comments