Skip to content

Instantly share code, notes, and snippets.

@lalizita
Created July 25, 2025 12:19
Show Gist options
  • Save lalizita/0f53cf9b90d8304f054ecce713a5c3eb to your computer and use it in GitHub Desktop.
Save lalizita/0f53cf9b90d8304f054ecce713a5c3eb to your computer and use it in GitHub Desktop.
Handling with connection errors in goroutines
package main
import (
"context"
"errors"
"fmt"
"math/rand"
"net"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
srvRun := true
servers := 10
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
var errCh = make(chan error, servers)
go handleConnectionErrors(ctx, errCh, cancel)
go start(ctx, servers, &srvRun, errCh)
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
<-quit
srvRun = false
fmt.Println("Shutting down gracefully...")
}
func handleConnectionErrors(ctx context.Context, errCh chan error, cancelFn context.CancelFunc) {
for {
select {
case <-ctx.Done():
fmt.Println("Context cancelled, shutting down error channel goroutine...")
return
case err := <-errCh:
if err != nil {
cancelFn()
return
}
}
}
}
func start(ctx context.Context, total int, srvRun *bool, errCh chan error) {
for i := 0; i < total; i++ {
fmt.Printf("Starting connection %d...\n", i+1)
go connect(ctx, srvRun, errCh)
}
}
func connect(ctx context.Context, srvRun *bool, errCh chan error) {
for *srvRun {
// Simulate connection logic ...
select {
case <-ctx.Done():
fmt.Println("Context cancelled, stopping connection...")
return
default:
handleConnection(ctx, errCh)
}
}
}
func handleConnection(ctx context.Context, errCh chan error) {
// Simulate handling connection ...
for {
select {
case <-ctx.Done():
fmt.Println("Context cancelled, stopping connection handling...")
return
case <-time.After(100 * time.Millisecond):
default:
if err := receive(); err != nil {
// Handle error ...
fmt.Printf("Error receiving data: %v\n", err)
errCh <- 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
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment