| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- // package kernel_keeper -- сторож системных сигналов.
- package kernel_keeper
- import (
- "context"
- "os"
- "os/signal"
- "sync"
- "syscall"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev0/helpers"
- mL1 "gitp78su.ipnodns.ru/svi/kern/v4/lev1"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev1/comp_spec"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev1/safe_bool"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kern_ent/stream_name"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kspec"
- )
- // kernelKeeper -- сторож системных сигналов.
- type kernelKeeper struct {
- ctx context.Context
- fnCancel func()
- wg kspec.IKernelWg
- log comp_spec.ILogBuf
- chSys_ chan os.Signal
- }
- var (
- kernKeep *kernelKeeper
- block sync.Mutex
- qName = stream_name.NewAStreamName(defs.TxtFix("kernel_keeper"))
- )
- // GetKernelKeeper -- возвращает новый сторож системных сигналов.
- func GetKernelKeeper(ctx context.Context, fnCancel func(),
- wg kspec.IKernelWg) *kernelKeeper {
- block.Lock()
- defer block.Unlock()
- if kernKeep != nil {
- kernKeep.log.Debug(defs.TxtFix("GetKernelKeeper()"))
- return kernKeep
- }
- helpers.If(ctx == nil).Hassert("NewKernelCtx(): ctx==nil", []any{})
- helpers.If(wg == nil).Hassert("NewKernelCtx(): IKernelWg==nil", []any{})
- helpers.If(fnCancel == nil).Hassert("NewKernelCtx(): fnCancel==nil", []any{})
- paramLogBuf := &mL1.LogBufParam{
- IsTerm_: safe_bool.NewSafeBool(true),
- Prefix_: defs.TxtFix("kernelKeeper"),
- }
- sf := &kernelKeeper{
- ctx: ctx,
- fnCancel: fnCancel,
- wg: wg,
- log: mL1.NewLogBuf(paramLogBuf),
- chSys_: make(chan os.Signal, 2),
- }
- sf.log.Debug(defs.TxtFix("GetKernelKeeper(): first run"))
- sf.wg.Add(qName)
- go sf.run(sf.chSys_)
- kernKeep = sf
- _ = kspec.IKernelKeeper(sf)
- return sf
- }
- // Log -- возвращает лог сторожа системных сигналов.
- func (sf *kernelKeeper) Log() comp_spec.ILogBuf {
- return sf.log
- }
- // Работает в отдельном потоке и ждёт сигналов прерываний работы.
- func (sf *kernelKeeper) run(chSys chan os.Signal) {
- sf.log.Debug(defs.TxtFix("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: // системный сигнал
- sf.log.Debug(defs.TxtFix("run(): system signal, sig=%v\n"), sig)
- sf.fnCancel()
- case <-sf.ctx.Done(): // сигнал от приложения
- sf.log.Debug(defs.TxtFix("run(): cancel app context, err=\n\t%v\n"), sf.ctx.Err())
- }
- sf.wg.Done(qName)
- sf.log.Debug(defs.TxtFix("run(): end"))
- }
|