Graceful Shutdown Example - gerbill/go GitHub Wiki

package main

import (
	"context"
	"fmt"
	"io"
	"net/http"
	"os/signal"
	"sync"
	"syscall"
	"time"
)

func main() {
	testShutdown()
}

func testShutdown() {
	wg := new(sync.WaitGroup)
	ctx, _ := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
	for i := 0; i < 100; i++ {
		go worker(ctx, wg, i)
	}
	wg.Wait()
}

func worker(ctx context.Context, wg *sync.WaitGroup, workerID int) {
	fmt.Printf("🚦 worker %d started | ", workerID)
	wg.Add(1)
	defer wg.Done()
	for {
		select {
		case <-ctx.Done():
			fmt.Printf("🚩 worker %d done | ", workerID)
			return
		case <-time.After(time.Second * 1):
			respBody := makeRequest("https://ip.oxton.ru")
			fmt.Printf("📡 worker %d: %d | ", workerID, len(respBody))
		}
	}
}

func makeRequest(url string) string {
	resp, err := http.Get(url)
	if err != nil {
		fmt.Printf("❌ Error: %s\n", err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("❌ Error reading body: %s\n", err)
	}
	return string(body)
}