From 7a323821087a5fa11f1e867d6a561ea1707ec4b0 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 6 Mar 2024 19:00:21 +0800 Subject: [PATCH] Avoid unexpected panic in graceful manager (#29629) (#29630) Backport #29629 (cherry picked from commit 2f1eb619bc19a9b172062ba17789356bbdaa259d) --- modules/graceful/manager_unix.go | 10 +++++++++- modules/graceful/manager_windows.go | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/modules/graceful/manager_unix.go b/modules/graceful/manager_unix.go index b1fd6da76d..67c97a6e7e 100644 --- a/modules/graceful/manager_unix.go +++ b/modules/graceful/manager_unix.go @@ -118,7 +118,15 @@ func (g *Manager) start(ctx context.Context) { defer close(startupDone) // Wait till we're done getting all of the listeners and then close // the unused ones - g.createServerWaitGroup.Wait() + func() { + // FIXME: there is a fundamental design problem of the "manager" and the "wait group". + // If nothing has started, the "Wait" just panics: sync: WaitGroup is reused before previous Wait has returned + // There is no clear solution besides a complete rewriting of the "manager" + defer func() { + _ = recover() + }() + g.createServerWaitGroup.Wait() + }() // Ignore the error here there's not much we can do with it // They're logged in the CloseProvidedListeners function _ = CloseProvidedListeners() diff --git a/modules/graceful/manager_windows.go b/modules/graceful/manager_windows.go index f676f86d04..6bcae9f747 100644 --- a/modules/graceful/manager_windows.go +++ b/modules/graceful/manager_windows.go @@ -227,7 +227,15 @@ func (g *Manager) awaitServer(limit time.Duration) bool { c := make(chan struct{}) go func() { defer close(c) - g.createServerWaitGroup.Wait() + func() { + // FIXME: there is a fundamental design problem of the "manager" and the "wait group". + // If nothing has started, the "Wait" just panics: sync: WaitGroup is reused before previous Wait has returned + // There is no clear solution besides a complete rewriting of the "manager" + defer func() { + _ = recover() + }() + g.createServerWaitGroup.Wait() + }() }() if limit > 0 { select {