github.com/lauslim12/expert-systems@v0.0.0-20221115131159-018513aad29c/cmd/expert-systems/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "net/http" 8 "os" 9 "os/signal" 10 "syscall" 11 "time" 12 13 "github.com/lauslim12/expert-systems/internal/application" 14 ) 15 16 // Constant for the web frontend location. 17 const pathToWebDirectory = "./web/build" 18 19 // Get port from environment variable. If it does not exist, use '8080'. 20 func getPort() string { 21 port := os.Getenv("PORT") 22 if port == "" { 23 return ":8080" 24 } 25 26 return fmt.Sprintf(":%s", port) 27 } 28 29 // Get application mode from environment variable 'GO_ENV'. If it does not exist, use 'development'. 30 func getMode() string { 31 mode := os.Getenv("GO_ENV") 32 if mode != "production" { 33 return "development" 34 } 35 36 return "production" 37 } 38 39 // Starting point, initialize server. 40 func main() { 41 // HTTP server initialization. 42 server := &http.Server{Addr: getPort(), Handler: application.Configure(pathToWebDirectory, getMode())} 43 44 // Prepare context for graceful shutdown. 45 serverCtx, serverStopCtx := context.WithCancel(context.Background()) 46 47 // Listen for syscall signals for process to interrupt or quit. 48 sig := make(chan os.Signal, 1) 49 signal.Notify(sig, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) 50 go func() { 51 <-sig 52 53 // Shutdown signal with grace period of 30 seconds. 54 shutdownCtx, shutdownCtxCancel := context.WithTimeout(serverCtx, 30*time.Second) 55 defer shutdownCtxCancel() 56 log.Println("Server starting to shutdown in 30 seconds...") 57 58 go func() { 59 <-shutdownCtx.Done() 60 if shutdownCtx.Err() == context.DeadlineExceeded { 61 log.Fatal("Graceful shutdown timeout, forcing exit.") 62 } 63 }() 64 65 // Trigger graceful shutdown here. 66 server.SetKeepAlivesEnabled(false) 67 if err := server.Shutdown(shutdownCtx); err != nil { 68 log.Fatalf("Could not gracefully shutdown the server: %v\n", err) 69 } 70 serverStopCtx() 71 }() 72 73 // Run our server and print out starting message. 74 log.Printf("Server has started on port %s with environment %s!", getPort(), getMode()) 75 err := server.ListenAndServe() 76 if err != nil && err != http.ErrServerClosed { 77 log.Fatal(err) 78 } 79 80 // Wait for server context to be stopped. 81 <-serverCtx.Done() 82 log.Println("Server shut down successfully!") 83 }