!= nil && !errors.Is(err, context.Canceled) { // 起動に失敗したら異常終了する log.Fatalln(err.Error()) } ctx, cancelT := context.WithTimeout(context.Background(), 10 * time.Second) // timeout時刻を過ぎたら強制終了する。 Contextは作り直さねばならない defer cancelT() var wg sync.WaitGroup wg.Add(1) go func(ctx context.Context) { // 複數のserverをparallelに終了させる defer wg.Done() stopped := make(chan struct{}) go func() { srv2.GracefulStop() close(stopped) }() select { case <-stopped: case <-ctx.Done(): // timeoutしたら強制終了する } }(ctx) wg.Wait() // 全てのserverが終了するのを待つ if err := context.Cause(ctx); err != nil && !errors.Is(err, context.Canceled) { // graceful shutdownに成功したら正常終了、失敗したら異常終了する log.Fatalln(err.Error()) } やればできるが、code記述量が多い