github.com/kumasuke120/mockuma@v1.1.9/internal/server/server.go (about)

     1  package server
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"log"
     7  	"net/http"
     8  	"strconv"
     9  	"sync"
    10  	"time"
    11  
    12  	"github.com/kumasuke120/mockuma/internal/mckmaps"
    13  )
    14  
    15  type MockServer struct {
    16  	port      int
    17  	server    *http.Server
    18  	serverMux sync.Mutex
    19  }
    20  
    21  func NewMockServer(port int) *MockServer {
    22  	s := new(MockServer)
    23  	s.port = port
    24  	return s
    25  }
    26  
    27  func (s *MockServer) ListenAndServe(mappings *mckmaps.MockuMappings) {
    28  	if mappings == nil {
    29  		panic("parameter 'mappings' should not be nil")
    30  	}
    31  
    32  	handler := newMockHandler(mappings)
    33  	addr := fmt.Sprintf(":%d", s.port)
    34  	server := &http.Server{Addr: addr, Handler: handler}
    35  
    36  	var wg sync.WaitGroup
    37  	wg.Add(1)
    38  	go func() {
    39  		defer wg.Done()
    40  
    41  		log.Println("[server  ] listening on " + strconv.Itoa(s.port) + "...")
    42  		if err := server.ListenAndServe(); err != nil {
    43  			if err != http.ErrServerClosed {
    44  				log.Fatalln("[server  ] cannot start:", err)
    45  			}
    46  		}
    47  	}()
    48  
    49  	s.setServer(server)
    50  	wg.Wait()
    51  }
    52  
    53  func (s *MockServer) SetMappings(mappings *mckmaps.MockuMappings) {
    54  	if mappings == nil {
    55  		panic("parameter 'mappings' should not be nil")
    56  	}
    57  
    58  	if ok := s.shutdown(); ok {
    59  		log.Println("[server  ] restarting with the new mockuMappings...")
    60  		go s.ListenAndServe(mappings)
    61  	}
    62  }
    63  
    64  func (s *MockServer) shutdown() bool {
    65  	server := s.getServer()
    66  	if server != nil {
    67  		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    68  		defer cancel()
    69  		if err := server.Shutdown(ctx); err != nil {
    70  			log.Fatalln("[server  ] cannot shutdown server in order to restart with the new mappings:", err)
    71  		}
    72  
    73  		return true
    74  	}
    75  
    76  	return false
    77  }
    78  
    79  func (s *MockServer) getServer() *http.Server {
    80  	s.serverMux.Lock()
    81  	defer s.serverMux.Unlock()
    82  	return s.server
    83  }
    84  
    85  func (s *MockServer) setServer(server *http.Server) {
    86  	s.serverMux.Lock()
    87  	defer s.serverMux.Unlock()
    88  	s.server = server
    89  }