Skip to content

Commit

Permalink
feat(cli): enhance signal handling for graceful shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
macrat committed Dec 10, 2022
1 parent 739e935 commit 817ace5
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 11 deletions.
9 changes: 5 additions & 4 deletions cmd/ayd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"fmt"
"io"
"os"
"os/signal"
"text/template"
"time"

"github.com/macrat/ayd/internal/scheme"
"github.com/macrat/ayd/internal/store"
Expand Down Expand Up @@ -38,7 +38,8 @@ type AydCommand struct {
ShowVersion bool
ShowHelp bool

Tasks []Task
Tasks []Task
StartedAt time.Time
}

var defaultAydCommand = &AydCommand{
Expand Down Expand Up @@ -142,8 +143,8 @@ func (cmd *AydCommand) Run(args []string) (exitCode int) {
return 1
}

ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

if len(cmd.AlertURLs) > 0 {
alert, err := scheme.NewAlerterSet(cmd.AlertURLs)
Expand Down
5 changes: 5 additions & 0 deletions cmd/ayd/oneshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package main

import (
"context"
"os/signal"
"sync"
"sync/atomic"
"syscall"

"github.com/macrat/ayd/internal/store"
api "github.com/macrat/ayd/lib-ayd"
Expand All @@ -12,6 +14,9 @@ import (
func (cmd *AydCommand) RunOneshot(ctx context.Context, s *store.Store) (exitCode int) {
var unhealthy atomic.Value

ctx, stop := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGHUP)
defer stop()

s.OnStatusChanged = append(s.OnStatusChanged, func(r api.Record) {
if r.Status != api.StatusHealthy {
unhealthy.Store(true)
Expand Down
43 changes: 36 additions & 7 deletions cmd/ayd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import (
"fmt"
"net/http"
"os"
"os/signal"
"sync"
"syscall"
"time"

"github.com/macrat/ayd/internal/endpoint"
Expand All @@ -14,7 +16,7 @@ import (
"github.com/robfig/cron/v3"
)

func (cmd *AydCommand) reportStartLog(s *store.Store, protocol, listen string) {
func (cmd *AydCommand) reportStartServer(s *store.Store, protocol, listen string) {
var tasks [][]string

for _, t := range cmd.Tasks {
Expand All @@ -24,12 +26,14 @@ func (cmd *AydCommand) reportStartLog(s *store.Store, protocol, listen string) {
})
}

cmd.StartedAt = time.Now()

u := &api.URL{Scheme: "ayd", Opaque: "server"}
s.Report(u, api.Record{
Time: time.Now(),
Time: cmd.StartedAt,
Status: api.StatusHealthy,
Target: u,
Message: fmt.Sprintf("start Ayd server"),
Message: "start Ayd server",
Extra: map[string]interface{}{
"url": fmt.Sprintf("%s://%s", protocol, listen),
"targets": tasks,
Expand All @@ -38,6 +42,21 @@ func (cmd *AydCommand) reportStartLog(s *store.Store, protocol, listen string) {
})
}

func (cmd *AydCommand) reportStopServer(s *store.Store, protocol, listen string) {
u := &api.URL{Scheme: "ayd", Opaque: "server"}
s.Report(u, api.Record{
Time: time.Now(),
Status: api.StatusHealthy,
Target: u,
Message: "stop Ayd server",
Extra: map[string]interface{}{
"url": fmt.Sprintf("%s://%s", protocol, listen),
"version": fmt.Sprintf("%s (%s)", version, commit),
"since": cmd.StartedAt.Format(time.RFC3339),
},
})
}

func (cmd *AydCommand) RunServer(ctx context.Context, s *store.Store) (exitCode int) {
startDebugLogger(s)

Expand All @@ -54,9 +73,6 @@ func (cmd *AydCommand) RunServer(ctx context.Context, s *store.Store) (exitCode
}
}

ctx, cancel := context.WithCancel(ctx)
defer cancel()

scheduler := cron.New()

if err := s.Restore(); err != nil {
Expand All @@ -65,7 +81,20 @@ func (cmd *AydCommand) RunServer(ctx context.Context, s *store.Store) (exitCode
}

listen := fmt.Sprintf("0.0.0.0:%d", cmd.ListenPort)
cmd.reportStartLog(s, protocol, listen)
cmd.reportStartServer(s, protocol, listen)

ctx, cancel := context.WithCancel(ctx)
go func() {
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGINT, syscall.SIGHUP)
select {
case <-ctx.Done():
case <-ch:
cmd.reportStopServer(s, protocol, listen)
cancel()
}
}()
defer cancel()

wg := &sync.WaitGroup{}
for _, t := range cmd.Tasks {
Expand Down

0 comments on commit 817ace5

Please sign in to comment.