Test HTTP server options before init/activation
Prevents full server initialization and activation on broken connections and when Corteza can not listen for HTTP requests.
This commit is contained in:
@@ -57,6 +57,12 @@ func (app *CortezaApp) InitCLI() {
|
||||
wg := &sync.WaitGroup{}
|
||||
|
||||
{ // @todo refactor wait-for out of HTTP API server.
|
||||
|
||||
// test http server options first
|
||||
if err = server.Test(app.Opt); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
app.HttpServer = server.New(app.Log, app.Opt)
|
||||
|
||||
wg.Add(1)
|
||||
|
||||
+34
-11
@@ -16,6 +16,9 @@ type (
|
||||
opts *options.Options
|
||||
endpoints []func(r chi.Router)
|
||||
|
||||
// last error
|
||||
err error
|
||||
|
||||
demux *demux
|
||||
}
|
||||
)
|
||||
@@ -31,10 +34,9 @@ const (
|
||||
// that demultiplexes request to one of the configured routers according to the server state.
|
||||
//
|
||||
// Waiting state
|
||||
// This is initial state that with some simple route handlers:
|
||||
// This is initial state with the ofllowing route handlers:
|
||||
// - /version
|
||||
// - /healthcheck
|
||||
// - /healthcheck
|
||||
|
||||
func New(log *zap.Logger, opts *options.Options) *server {
|
||||
s := &server{
|
||||
@@ -50,6 +52,23 @@ func New(log *zap.Logger, opts *options.Options) *server {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *server) LastError() error {
|
||||
return s.err
|
||||
}
|
||||
|
||||
func Test(o *options.Options) error {
|
||||
listener, err := net.Listen("tcp", o.HTTPServer.Addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = listener.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Activate reconfigures server to use active routes
|
||||
func (s *server) Activate(mm ...func(chi.Router)) {
|
||||
s.demux.Router(active, activeRoutes(s.log, mm, s.opts))
|
||||
@@ -65,6 +84,10 @@ func (s *server) Shutdown() {
|
||||
}
|
||||
|
||||
func (s server) Serve(ctx context.Context) {
|
||||
var (
|
||||
listener net.Listener
|
||||
)
|
||||
|
||||
s.log.Info(
|
||||
"starting HTTP server",
|
||||
|
||||
@@ -72,9 +95,9 @@ func (s server) Serve(ctx context.Context) {
|
||||
zap.String("address", s.opts.HTTPServer.Addr),
|
||||
)
|
||||
|
||||
listener, err := net.Listen("tcp", s.opts.HTTPServer.Addr)
|
||||
if err != nil {
|
||||
s.log.Error("cannot start server", zap.Error(err))
|
||||
listener, s.err = net.Listen("tcp", s.opts.HTTPServer.Addr)
|
||||
if s.err != nil {
|
||||
s.log.Error("cannot start server", zap.Error(s.err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -87,16 +110,16 @@ func (s server) Serve(ctx context.Context) {
|
||||
// this enables us to send cancellation down to every request
|
||||
BaseContext: func(listener net.Listener) context.Context { return ctx },
|
||||
}
|
||||
err = srv.Serve(listener)
|
||||
s.err = srv.Serve(listener)
|
||||
}()
|
||||
<-ctx.Done()
|
||||
|
||||
if err == nil {
|
||||
err = ctx.Err()
|
||||
if err == context.Canceled {
|
||||
err = nil
|
||||
if s.err == nil {
|
||||
s.err = ctx.Err()
|
||||
if s.err == context.Canceled {
|
||||
s.err = nil
|
||||
}
|
||||
}
|
||||
|
||||
s.log.Info("HTTP server stopped", zap.Error(err))
|
||||
s.log.Info("HTTP server stopped", zap.Error(s.err))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user