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 }