Last active
July 25, 2025 13:03
-
-
Save gandarez/e6db969ce8e3230978401162653f253f to your computer and use it in GitHub Desktop.
panic: sync: negative WaitGroup counter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "errors" | |
| "fmt" | |
| "math/rand" | |
| "net" | |
| "os" | |
| "os/signal" | |
| "sync" | |
| "syscall" | |
| "time" | |
| ) | |
| func main() { | |
| srvRun := true | |
| go start(10, &srvRun) | |
| quit := make(chan os.Signal, 1) | |
| signal.Notify(quit, os.Interrupt, syscall.SIGTERM) | |
| <-quit | |
| srvRun = false | |
| fmt.Println("Shutting down gracefully...") | |
| } | |
| func start(total int, srvRun *bool) { | |
| var wg sync.WaitGroup | |
| for i := range total { | |
| fmt.Printf("Starting connection %d...\n", i+1) | |
| wg.Add(1) | |
| go connect(srvRun, &wg) | |
| } | |
| wg.Wait() | |
| } | |
| func connect(srvRun *bool, wg *sync.WaitGroup) { | |
| for *srvRun { | |
| // Simulate connection logic ... | |
| handleConnection(wg) | |
| } | |
| } | |
| func handleConnection(wg *sync.WaitGroup) { | |
| defer wg.Done() | |
| // Simulate handling connection ... | |
| for { | |
| select { | |
| case <-time.After(100 * time.Millisecond): | |
| default: | |
| if err := receive(); err != nil { | |
| // Handle error ... | |
| fmt.Printf("Error receiving data: %v\n", err) | |
| return | |
| } | |
| } | |
| } | |
| } | |
| func receive() error { | |
| // Simulate receiving data ... | |
| time.Sleep(200 * time.Millisecond) | |
| r := rand.Intn(20-1) + 1 | |
| if r%2 == 0 { | |
| // Simulate an error condition | |
| return &net.OpError{Op: "receive", Err: errors.New("simulated error")} | |
| } | |
| return nil | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A solução mais simples para esse problema, sem pensar em qualquer mecanismo de retry ou se preocupar com o total de goroutines em execução, é retornar erro na função
handleConnectione tratar esse erro na funçãoconnect. Dessa forma qualquer erro agora é retornado ao chamador e ele vai abortar o loop não fazendo com que ahandleConnectionseja chamada novamente causando o decremento de forma acidental do wait group.