mirror of
https://github.com/foomo/keel.git
synced 2025-10-16 12:35:34 +00:00
wip: optimize graceful shutdown
This commit is contained in:
parent
3dd86ae626
commit
e100f0730a
@ -4,8 +4,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/foomo/keel/interfaces"
|
||||||
"github.com/foomo/keel/service"
|
"github.com/foomo/keel/service"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
@ -15,6 +17,7 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
svr := keel.NewServer(
|
svr := keel.NewServer(
|
||||||
|
//keel.WithLogger(zap.NewExample()),
|
||||||
keel.WithHTTPZapService(true),
|
keel.WithHTTPZapService(true),
|
||||||
keel.WithHTTPViperService(true),
|
keel.WithHTTPViperService(true),
|
||||||
keel.WithHTTPPrometheusService(true),
|
keel.WithHTTPPrometheusService(true),
|
||||||
@ -28,15 +31,70 @@ func main() {
|
|||||||
// create demo service
|
// create demo service
|
||||||
svs := http.NewServeMux()
|
svs := http.NewServeMux()
|
||||||
svs.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
svs.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
l.Info("handling request...")
|
||||||
|
time.Sleep(3 * time.Second)
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
_, _ = w.Write([]byte("OK"))
|
_, _ = w.Write([]byte("OK"))
|
||||||
|
l.Info("... handled request")
|
||||||
})
|
})
|
||||||
|
|
||||||
svr.AddService(
|
svr.AddService(
|
||||||
service.NewHTTP(l, "demo", "localhost:8080", svs),
|
service.NewHTTP(l, "demo", "localhost:8080", svs),
|
||||||
)
|
)
|
||||||
|
|
||||||
svr.Run()
|
svr.AddCloser(interfaces.CloseFunc(func(ctx context.Context) error {
|
||||||
|
l.Info("custom closer")
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
|
||||||
|
go svr.Run()
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
l.Info("1. starting test")
|
||||||
|
|
||||||
|
{
|
||||||
|
l.Info("2. checking healthz")
|
||||||
|
readiness(l, "http://localhost:9400/healthz/readiness")
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
l.Info("2. sending request")
|
||||||
|
if r, err := http.Get("http://localhost:8080"); err != nil {
|
||||||
|
l.Fatal(err.Error())
|
||||||
|
} else {
|
||||||
|
l.Info(" /", zap.Int("status", r.StatusCode))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
|
l.Info("3. sending shutdown signal")
|
||||||
|
if err := syscall.Kill(syscall.Getpid(), syscall.SIGTERM); err != nil {
|
||||||
|
l.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
l.Info("2. checking healthz")
|
||||||
|
readiness(l, "http://localhost:9400/healthz/readiness")
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Info("4. waiting for shutdown")
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
l.Info(" done")
|
||||||
|
}
|
||||||
|
|
||||||
|
func readiness(l *zap.Logger, url string) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
||||||
|
defer cancel()
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
l.Error(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
l.Error(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
l.Info(url, zap.Int("status", resp.StatusCode))
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitGroup(ctx context.Context, l *zap.Logger) {
|
func waitGroup(ctx context.Context, l *zap.Logger) {
|
||||||
|
|||||||
@ -4,6 +4,14 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type CloseHandler struct {
|
||||||
|
Value func(ctx context.Context) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r CloseHandler) Close(ctx context.Context) error {
|
||||||
|
return r.Value(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
// Closer interface
|
// Closer interface
|
||||||
type Closer interface {
|
type Closer interface {
|
||||||
Close()
|
Close()
|
||||||
@ -23,3 +31,9 @@ type CloserWithContext interface {
|
|||||||
type ErrorCloserWithContext interface {
|
type ErrorCloserWithContext interface {
|
||||||
Close(ctx context.Context) error
|
Close(ctx context.Context) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CloseFunc(v func(ctx context.Context) error) CloseHandler {
|
||||||
|
return CloseHandler{
|
||||||
|
Value: v,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -65,7 +65,7 @@ type Server struct {
|
|||||||
func NewServer(opts ...Option) *Server {
|
func NewServer(opts ...Option) *Server {
|
||||||
inst := &Server{
|
inst := &Server{
|
||||||
shutdownTimeout: 30 * time.Second,
|
shutdownTimeout: 30 * time.Second,
|
||||||
shutdownSignals: []os.Signal{os.Interrupt, syscall.SIGTERM},
|
shutdownSignals: []os.Signal{syscall.SIGTERM},
|
||||||
syncReadmers: []interfaces.Readmer{},
|
syncReadmers: []interfaces.Readmer{},
|
||||||
syncProbes: map[healthz.Type][]interface{}{},
|
syncProbes: map[healthz.Type][]interface{}{},
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user