this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

cmd/grace/main.go

Signed-off-by: Seongmin Lee <git@boltless.me>

+101
+101
cmd/grace/main.go
··· 1 + package main 2 + 3 + import ( 4 + "context" 5 + "fmt" 6 + "log" 7 + "net" 8 + "net/http" 9 + "os" 10 + "os/signal" 11 + "sync" 12 + "syscall" 13 + "time" 14 + ) 15 + 16 + type Config struct { 17 + Host string 18 + Port string 19 + } 20 + 21 + func NewConfig() Config { 22 + return Config{ 23 + Host: "127.0.0.1", 24 + Port: "8080", 25 + } 26 + } 27 + 28 + func run(ctx context.Context) error { 29 + ctx, stop := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM) 30 + defer stop() 31 + 32 + // setup process 33 + cfg := NewConfig() 34 + httpServer := &http.Server{ 35 + Addr: net.JoinHostPort(cfg.Host, cfg.Port), 36 + Handler: NewRoute(), 37 + BaseContext: func(l net.Listener) context.Context { 38 + return ctx 39 + }, 40 + } 41 + go func() { 42 + log.Printf("listening on %s\n", httpServer.Addr) 43 + if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { 44 + fmt.Fprintf(os.Stderr, "error listening and serving: %s\n", err) 45 + } 46 + }() 47 + 48 + log.Println("server intialized successfully") 49 + 50 + // listen to signal 51 + <-ctx.Done() 52 + stop() // allow second CTRL-C to forcefully terminate the process 53 + 54 + // graceful shutdown 55 + func() { 56 + // new context from background for graceful shutdown 57 + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) 58 + defer cancel() 59 + 60 + var wg sync.WaitGroup 61 + wg.Go(func() { 62 + log.Println("graceful http server shutdown") 63 + if err := httpServer.Shutdown(ctx); err != nil { 64 + fmt.Fprintf(os.Stderr, "error shutting down http server: %s\n", err) 65 + } 66 + }) 67 + wg.Go(func() { 68 + log.Println("graceful backgroud job shutdown") 69 + select { 70 + case <-ctx.Done(): 71 + ctx.Err() 72 + case <-time.After(8 * time.Second): 73 + } 74 + }) 75 + wg.Wait() 76 + 77 + log.Println("server exited gracefully") 78 + }() 79 + return nil 80 + } 81 + 82 + func NewRoute() http.Handler { 83 + mux := http.NewServeMux() 84 + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 85 + for range 15 { 86 + log.Println("serving...") 87 + time.Sleep(2 * time.Second); 88 + } 89 + w.WriteHeader(http.StatusOK) 90 + }) 91 + return mux 92 + } 93 + 94 + func main() { 95 + ctx := context.Background() 96 + 97 + if err := run(ctx); err != nil { 98 + fmt.Fprintf(os.Stderr, "%s\n", err) 99 + os.Exit(1) 100 + } 101 + }