| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- // package kernel_keeper -- сторож системных сигналов
- package kernel_keeper
- import (
- "context"
- "log"
- "os"
- "os/signal"
- "syscall"
- . "wartank/pkg/helpers"
- . "wartank/pkg/kernel/kernel_types"
- )
- // kernelKeeper -- сторож системных сигналов
- type kernelKeeper struct {
- ctx context.Context
- fnCancel func()
- wg IKernelWg
- chSys_ chan os.Signal
- }
- var (
- kernKeep *kernelKeeper
- )
- // GetKernelKeeper -- возвращает новый сторож системных сигналов
- func GetKernelKeeper(ctx context.Context, fnCancel func(), wg IKernelWg) *kernelKeeper {
- if kernKeep != nil {
- return kernKeep
- }
- Паника(ctx != nil, "NewKernelCtx(): ctx==nil")
- Паника(wg != nil, "NewKernelCtx(): IKernelWg==nil")
- Паника(fnCancel != nil, "NewKernelCtx(): fnCancel==nil")
- sf := &kernelKeeper{
- ctx: ctx,
- fnCancel: fnCancel,
- wg: wg,
- chSys_: make(chan os.Signal, 2),
- }
- err := sf.wg.Add("kernel_keeper")
- Паника(err == nil, "NewKernelCtx(): in add stream kernel keeper in IKernelWg, err=\n\t%v,err")
- go sf.run(sf.chSys_)
- kernKeep = sf
- _ = IKernelKeeper(sf)
- return sf
- }
- // Работает в отдельном потоке и ждёт сигналов прерываний работы
- func (sf *kernelKeeper) run(chSys chan os.Signal) {
- log.Println("kernelKeeper.run()")
- // Регистрируем сигналы SIGINT (Ctrl+C) и SIGTERM (завершение процесса)
- // syscall.SIGHUP: Сигнал, отправляемый при закрытии терминала.
- // syscall.SIGQUIT: Сигнал, отправляемый при нажатии **Ctrl+**.
- signal.Notify(chSys, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT)
- select {
- case sig := <-chSys: // системный сигнал
- log.Printf("kernelKeeper.run(): system signal, sig=%v\n", sig)
- sf.fnCancel()
- case <-sf.ctx.Done(): // сигнал от приложения
- log.Printf("kernelKeeper.run(): cancel app context, err=\n\t%v\n", sf.ctx.Err())
- }
- sf.wg.Done("kernel_keeper")
- log.Printf("kernelKeeper.run(): end")
- }
|