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) } }