| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- package keeper
- /*
- Сторож системных сигналов.
- Мониторит ОС и части сервиса на завершение работы.
- В системе он должен быть только один.
- */
- import (
- "fmt"
- "os"
- "os/signal"
- "syscall"
- "wartank/pkg/types"
- )
- // Сторож -- сторож системных и внутренних сигналов
- type Сторож struct {
- kernel types.ИЯдро
- слог types.ИСлог
- chSys chan os.Signal
- }
- const (
- стрСторож = "сторож"
- )
- // НовСторож -- возвращает глобальный объект сторожа *Keeper
- func НовСторож(kernel types.ИЯдро) *Сторож {
- if kernel == nil {
- panic("GetKeeper(): IKernel is nil")
- }
- сам := &Сторож{
- kernel: kernel,
- слог: kernel.Слог(),
- chSys: make(chan os.Signal, 3),
- }
- ош := сам.kernel.Wg().Add(стрСторож)
- if ош != nil {
- panic(fmt.Sprintf("НовСторож(): при добавлении группы ожидания %q, ош=\n\t%v\n", стрСторож, ош.Error()))
- }
- signal.Notify(сам.chSys, os.Interrupt, syscall.SIGTERM)
- go сам.run()
- сам.слог.Отладка("NewKeeper()\n")
- return сам
- }
- // Слушает сигналы завершения изнутри и снаружи
- func (сам *Сторож) run() {
- сам.слог.Инфо("Keeper.run()\n")
- defer func() {
- сам.слог.Инфо("Keeper.run(): end\n")
- ош := сам.kernel.Wg().Done(стрСторож)
- if ош != nil {
- сам.слог.Ошибка("Keeper.run(): при удалении группы ожидания, ош=\n\t%w", ош)
- }
- }()
- select {
- case sig := <-сам.kernel.Done(): // глобальная отмена контекста
- сам.слог.Инфо("Keeper.run(): intern_sig=%q\n", sig)
- case sig := <-сам.chSys: // Системный сигнал закрытия
- сам.kernel.Отменить()
- сам.слог.Инфо("Keeper.run(): sys_sig=%v\n", sig)
- }
- }
|