kernel_keeper.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // package kernel_keeper -- сторож системных сигналов
  2. package kernel_keeper
  3. import (
  4. "context"
  5. "log"
  6. "os"
  7. "os/signal"
  8. "syscall"
  9. . "wartank/pkg/helpers"
  10. . "wartank/pkg/kernel/kernel_types"
  11. )
  12. // kernelKeeper -- сторож системных сигналов
  13. type kernelKeeper struct {
  14. ctx context.Context
  15. fnCancel func()
  16. wg IKernelWg
  17. chSys_ chan os.Signal
  18. }
  19. var (
  20. kernKeep *kernelKeeper
  21. )
  22. // GetKernelKeeper -- возвращает новый сторож системных сигналов
  23. func GetKernelKeeper(ctx context.Context, fnCancel func(), wg IKernelWg) *kernelKeeper {
  24. if kernKeep != nil {
  25. return kernKeep
  26. }
  27. Паника(ctx != nil, "NewKernelCtx(): ctx==nil")
  28. Паника(wg != nil, "NewKernelCtx(): IKernelWg==nil")
  29. Паника(fnCancel != nil, "NewKernelCtx(): fnCancel==nil")
  30. sf := &kernelKeeper{
  31. ctx: ctx,
  32. fnCancel: fnCancel,
  33. wg: wg,
  34. chSys_: make(chan os.Signal, 2),
  35. }
  36. err := sf.wg.Add("kernel_keeper")
  37. Паника(err == nil, "NewKernelCtx(): in add stream kernel keeper in IKernelWg, err=\n\t%v,err")
  38. go sf.run(sf.chSys_)
  39. kernKeep = sf
  40. _ = IKernelKeeper(sf)
  41. return sf
  42. }
  43. // Работает в отдельном потоке и ждёт сигналов прерываний работы
  44. func (sf *kernelKeeper) run(chSys chan os.Signal) {
  45. log.Println("kernelKeeper.run()")
  46. // Регистрируем сигналы SIGINT (Ctrl+C) и SIGTERM (завершение процесса)
  47. // syscall.SIGHUP: Сигнал, отправляемый при закрытии терминала.
  48. // syscall.SIGQUIT: Сигнал, отправляемый при нажатии **Ctrl+**.
  49. signal.Notify(chSys, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT)
  50. select {
  51. case sig := <-chSys: // системный сигнал
  52. log.Printf("kernelKeeper.run(): system signal, sig=%v\n", sig)
  53. sf.fnCancel()
  54. case <-sf.ctx.Done(): // сигнал от приложения
  55. log.Printf("kernelKeeper.run(): cancel app context, err=\n\t%v\n", sf.ctx.Err())
  56. }
  57. sf.wg.Done("kernel_keeper")
  58. log.Printf("kernelKeeper.run(): end")
  59. }