21/01/2024 - GO
Bu örnekte, aktif olarak çalışan istekleri bir süre bekleyip (5 saniye), eğer daha uzun sürerlerse onları öldürmeden önce signal.NotifyContext
'i kullanacağız.
package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
type app struct {
server *http.Server
shutdown time.Duration
}
func (a app) start() error {
if err := a.server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
return err
}
return nil
}
func (a app) stop(ctx context.Context) error {
ctxNotify, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM)
<-ctxNotify.Done()
stop()
ctxTimeout, cancel := context.WithTimeout(ctx, a.shutdown)
defer cancel()
if err := a.server.Shutdown(ctxTimeout); err != nil {
return err
}
return nil
}
func main() {
handler := http.DefaultServeMux
handler.HandleFunc("/", home)
server := &http.Server{
Addr: ":1234",
Handler: handler,
}
app := app{
server: server,
shutdown: time.Second * 5,
}
go func() {
log.Println("app is running")
if err := app.start(); err != nil {
log.Println("app start:", err)
return
}
}()
if err := app.stop(context.Background()); err != nil {
log.Println("dirty app stop with possible interruptions:", err)
} else {
log.Println("clean app stop without any interruption")
}
}
func home(w http.ResponseWriter, r *http.Request) {
log.Println("in")
time.Sleep(time.Second * 10) <- Adjust this in tests
log.Println("out")
}
$ curl http://0.0.0.0:1234/
çağrıldığında ctrl+c
tuşlarını kullanın.
time.Sleep(time.Second * 2)
$ go run -race main.go
2024/01/21 14:02:14 app is running
2024/01/21 14:02:35 in
^C
2024/01/21 14:02:37 out
2024/01/21 14:02:37 clean app stop without any interruption
time.Sleep(time.Second * 8)
$ go run -race main.go
2024/01/21 14:03:28 app is running
2024/01/21 14:03:32 in
^C
2024/01/21 14:03:37 dirty app stop with possible interruptions: context deadline exceeded