src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

server.go (2218B)


      1 package server
      2 
      3 import (
      4 	"context"
      5 	"fmt"
      6 	"net/http"
      7 	"runtime/debug"
      8 
      9 	"code.dwrz.net/src/pkg/log"
     10 )
     11 
     12 type Server struct {
     13 	cfg   *Config
     14 	log   *log.Logger
     15 	http  *http.Server
     16 	https *http.Server
     17 }
     18 
     19 func (s *Server) Serve() {
     20 	if s.http != nil {
     21 		s.log.Debug.Printf("serving http")
     22 
     23 		go func() {
     24 			if msg := recover(); msg != nil {
     25 				s.log.Error.Printf(
     26 					"panic: %v:\n%s\n", msg, debug.Stack(),
     27 				)
     28 			}
     29 
     30 			s.serveHTTP()
     31 		}()
     32 	}
     33 	if s.https != nil {
     34 		s.log.Debug.Printf("serving https")
     35 
     36 		go func() {
     37 			if msg := recover(); msg != nil {
     38 				s.log.Error.Printf(
     39 					"panic: %v:\n%s\n", msg, debug.Stack(),
     40 				)
     41 			}
     42 
     43 			s.serveHTTPS()
     44 		}()
     45 
     46 	}
     47 
     48 	s.log.Debug.Printf("server ready")
     49 }
     50 
     51 func (s *Server) serveHTTP() {
     52 	s.log.Debug.Printf("starting http server (%s)", s.http.Addr)
     53 
     54 	if err := s.http.ListenAndServe(); err != http.ErrServerClosed {
     55 		s.log.Error.Fatalf(
     56 			"failed to listen and serve: %v", err,
     57 		)
     58 	}
     59 }
     60 
     61 func (s *Server) serveHTTPS() {
     62 	s.log.Debug.Printf("starting https server (%s)", s.https.Addr)
     63 
     64 	if err := s.https.ListenAndServeTLS(
     65 		"", "",
     66 	); err != http.ErrServerClosed {
     67 		s.log.Error.Fatalf(
     68 			"failed to listen and serve: %v", err,
     69 		)
     70 	}
     71 }
     72 
     73 func (s *Server) Shutdown() error {
     74 	s.log.Debug.Printf("shutting down server")
     75 
     76 	ctxShutdown, cancel := context.WithTimeout(
     77 		context.Background(), s.cfg.Timeouts.Shutdown,
     78 	)
     79 	defer cancel()
     80 
     81 	var httpShutdownErr, httpsShutdownErr error
     82 	if s.http != nil {
     83 		s.http.SetKeepAlivesEnabled(false)
     84 
     85 		if err := s.http.Shutdown(ctxShutdown); err != nil {
     86 			httpShutdownErr = err
     87 		}
     88 	}
     89 	if s.https != nil {
     90 		s.https.SetKeepAlivesEnabled(false)
     91 
     92 		if err := s.https.Shutdown(ctxShutdown); err != nil {
     93 			httpsShutdownErr = err
     94 		}
     95 	}
     96 
     97 	switch {
     98 	case httpShutdownErr != nil && httpsShutdownErr != nil:
     99 		return fmt.Errorf(
    100 			"failed to shut down http and https servers: %v, %v",
    101 			httpShutdownErr, httpsShutdownErr,
    102 		)
    103 	case httpShutdownErr != nil:
    104 		return fmt.Errorf(
    105 			"failed to shut down http server: %v", httpShutdownErr,
    106 		)
    107 	case httpsShutdownErr != nil:
    108 		return fmt.Errorf(
    109 			"failed to shut down https server: %v",
    110 			httpsShutdownErr,
    111 		)
    112 	default:
    113 		s.log.Debug.Printf("server shutdown")
    114 
    115 		return nil
    116 	}
    117 }