慕的地8271018
作为第一步,让我们创建一个通道并将其绑定到您感兴趣的领域中的信号。然后您需要创建上下文并在收到此信号时触发取消功能。c := make(chan os.Signal, 1)signal.Notify(c, os.Interrupt)ctx, cancel := context.WithCancel(context.Background()) // pass your ctx in all goroutines as first argument, go func() { signal := <-c logger.Info("signal was received", zap.Stringer("signal", signal) cancel()}()然后,您可以创建WaitGroup上下文并将其作为每个 goroutine 中的第一个参数传递wg := &sync.WaitGroup{}hooks.RunStartHooks(ctx, wg)在您的工作人员内部,按照文档中的规定,聆听与 wg 一起正常工作的上下文取消for { select { case <-ctx.Done(): wg.Done() return } // other cases}最后, timeout := cfg.Server.HooksCloseTimeout // this is from your config if waitTimeout(wg, timeout) { logger.Info("timed out waiting for wait group") } else { logger.Info("server exited properly") }waitTimeout 在哪里// waitTimeout waits for the waitgroup for the specified max timeout.// Returns true if waiting timed out.func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool { c := make(chan struct{}) go func() { defer close(c) wg.Wait() }() select { case <-c: return false // completed normally case <-time.After(timeout): return true // timed out }}