Skip to content

Instantly share code, notes, and snippets.

@kawasin73
Created February 8, 2020 02:17
Show Gist options
  • Save kawasin73/28ade00aa694143fbacc013be0a54a1a to your computer and use it in GitHub Desktop.
Save kawasin73/28ade00aa694143fbacc013be0a54a1a to your computer and use it in GitHub Desktop.
package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"sync"
"syscall"
"time"
)
func run(ctx context.Context) error {
for {
select {
case <-ctx.Done():
return ctx.Err()
}
}
}
func main() {
srv := &http.Server{
Addr: ":8080",
}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
var wg sync.WaitGroup
wg.Add(3)
go func() {
defer wg.Done()
log.Println(run(ctx))
cancel()
}()
go func() {
defer wg.Done()
log.Println(run(ctx))
cancel()
}()
go func() {
defer wg.Done()
log.Println(srv.ListenAndServe())
cancel()
}()
quit := make(chan os.Signal, 1)
defer close(quit)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
fmt.Println("start!")
// シグナルかコンテキストキャンセルを受ける
select {
case <-quit:
fmt.Println("received signal")
cancel()
case <-ctx.Done():
fmt.Println("received context cancel")
}
if err := srv.Shutdown(ctx); err != nil {
log.Println(err)
}
// doneを読んだら全てのgorutineが確実に終了することが前提の実装になっている
wg.Wait()
fmt.Println("done")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment