123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- package ctrlc
- import (
- "context"
- "fmt"
- "os"
- "os/signal"
- "strings"
- "syscall"
- "time"
- )
- const C_ICON_START = "🌟"
- const C_ICON_WARN = "⚡️"
- const C_ICON_HOT = "🔥"
- const C_ICON_MAG = "✨"
- const C_ICON_SC = "🌳"
- type Iface interface {
- Shutdown(ctx context.Context) error
- }
- type CallbackFunc func(ctx context.Context, shutdown context.CancelFunc) *[]Iface
- func App(t time.Duration, f CallbackFunc) {
- stop := make(chan os.Signal)
- signal.Notify(stop, syscall.SIGTERM)
- signal.Notify(stop, syscall.SIGINT)
- fmt.Printf(
- icon_start(UseColors())+"%s\n",
- cly(
- UseColors(),
- fmt.Sprintf(
- "Application started (%d sec)",
- t/time.Second,
- ),
- ),
- )
- sctx, shutdown := context.WithCancel(context.Background())
- ifaces := f(sctx, shutdown)
- select {
- case <-sctx.Done():
- fmt.Printf(
- "\r"+icon_warn(UseColors())+"%s\n",
- cly(
- UseColors(),
- fmt.Sprintf(
- "Shutting down (application) (%d sec)",
- t/time.Second,
- ),
- ),
- )
- case val := <-stop:
- switch val {
- case syscall.SIGINT:
- fmt.Printf(
- "\r"+icon_warn(UseColors())+"%s\n",
- cly(
- UseColors(),
- fmt.Sprintf(
- "Shutting down (interrupt) (%d sec)",
- t/time.Second,
- ),
- ),
- )
- case syscall.SIGTERM:
- fmt.Printf(
- icon_warn(UseColors())+"%s\n",
- cly(
- UseColors(),
- fmt.Sprintf(
- "Shutting down (terminate) (%d sec)",
- t/time.Second,
- ),
- ),
- )
- default:
- fmt.Printf(
- icon_warn(UseColors())+"%s\n",
- cly(
- UseColors(),
- fmt.Sprintf(
- "Shutting down (%d sec)",
- t/time.Second,
- ),
- ),
- )
- }
- }
- shutdown()
- errors := false
- ctx, cancel := context.WithTimeout(context.Background(), t)
- for _, iface := range *ifaces {
- if err := iface.Shutdown(ctx); err != nil {
- errors = true
- fmt.Printf(
- icon_hot(UseColors())+"%s\n",
- clr(
- UseColors(),
- fmt.Sprintf(
- "Shutdown error (%T): %s",
- iface,
- err.Error(),
- ),
- ),
- )
- }
- }
- cancel()
- if errors {
- fmt.Printf(
- icon_mag(UseColors())+"%s\n",
- cly(
- UseColors(),
- fmt.Sprintf(
- "Application exited with errors (%d sec)",
- t/time.Second,
- ),
- ),
- )
- os.Exit(1)
- } else {
- fmt.Printf(
- icon_sc(UseColors())+"%s\n",
- clg(
- UseColors(),
- fmt.Sprintf(
- "Application exited successfully (%d sec)",
- t/time.Second,
- ),
- ),
- )
- }
- }
- func UseColors() bool {
- useColors := strings.Contains(
- fmt.Sprintf("%s", os.Args),
- "--color=always",
- )
- if !useColors {
- useColors = strings.Contains(
- fmt.Sprintf("%s", os.Args),
- "-color=always",
- )
- }
- if !useColors {
- useColors = strings.Contains(
- fmt.Sprintf("%s", os.Args),
- "color=always",
- )
- }
- if !useColors {
- useColors = strings.Contains(
- fmt.Sprintf("%s", os.Args),
- "--color always",
- )
- }
- if !useColors {
- useColors = strings.Contains(
- fmt.Sprintf("%s", os.Args),
- "-color always",
- )
- }
- if !useColors {
- useColors = strings.Contains(
- fmt.Sprintf("%s", os.Args),
- "color always",
- )
- }
- return !IS_WIN_PLATFORM && useColors
- }
|