Go v1.16 추가 시그널.NotifyContext 테스트

3950 단어 Gotech
Go v1.16 나왔네요!
https://golang.org/doc/go1.16
많은 기능이 추가되었는데 이번에는 시그널입니다.Notify Context 해볼게요!
https://future-architect.github.io/articles/20210207/

signal.Notify Context는 무엇을 할 수 있습니까?


신호를 쉽게 써서 상하문cancel을 처리할 수 있다.
https://golang.org/pkg/os/signal/#NotifyContext

이전의 서법


지금까지 signal.Notify로 신호를 포착하고 context.WithCancel로 작성한 상하문cancel의 처리가 필요하다.
package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"time"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	go func() {
		select {
		case <-c:
			fmt.Fprintln(os.Stderr, "signal received")
			cancel()
		case <-ctx.Done():
		}
	}()

	doSomethingAwesome(ctx)
}

signal.NotifyContext 쓰기 사용

signal.NotifyContext를 사용하면 이렇게 간단해진다.
package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"time"
)

func main() {
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()

	doSomethingAwesome(ctx)
}

signal.NotifyContext 사용 예


여러 개의 Goroutine를 시작하고 signal로 한꺼번에 끝냅니다


package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"sync"
)

func blocking(ctx context.Context, wg *sync.WaitGroup) {
	defer wg.Done()
	fmt.Println("worker started")
	<-ctx.Done()
	fmt.Println("worker canceled")
}

func main() {
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()

	var wg sync.WaitGroup
	wg.Add(3)
	go blocking(ctx, &wg)
	go blocking(ctx, &wg)
	go blocking(ctx, &wg)

	wg.Wait()
}

웹 서버를 꺼서graceful로 만들기


package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"os/signal"
	"time"
)

func main() {
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		io.WriteString(w, "hello!")
	})

	server := &http.Server{
		Addr:    ":8080",
		Handler: nil,
	}
	go func() {
		<-ctx.Done()
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()
		server.Shutdown(ctx)
	}()
	fmt.Println("starting server at :8080")
	log.Fatal(server.ListenAndServe())
}

최후

  • signal.NotifyContext를 사용하면 신호를 더욱 간단하게 처리할 수 있다
  • 게으름을 많이 피워서 신호 처리를 하지 않기 때문에 잘 하세요
  • 참고 자료


    https://github.com/nekoshita/golang-signal-notify-context-example
    https://golang.org/pkg/os/signal/#NotifyContext
    https://future-architect.github.io/articles/20210212/
    https://mattn.kaoriya.net/software/lang/go/20200916090416.htm

    좋은 웹페이지 즐겨찾기