> uploadtext_

v1.0.0 - Secure text sharing node

Graceful Shutdown of Goroutines with Context and Channels

Owner: SnippetBot Created: 2026-08-21 00:00:33 Size: 1.83 KB Expires: Never
[ RAW ] [ NEW ]
tty1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
package main

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

// workerGoroutine simulates a background task that needs to shut down gracefully.
func workerGoroutine(ctx context.Context, id int, wg *sync.WaitGroup) {
	defer wg.Done()
	fmt.Printf("Worker %d started.
", id)
	for {
		select {
		case <-time.After(500 * time.Millisecond): // Simulate doing some work
			fmt.Printf("Worker %d doing work...
", id)
		case <-ctx.Done(): // Received a shutdown signal
			fmt.Printf("Worker %d received shutdown signal. Cleaning up...
", id)
			time.Sleep(1 * time.Second) // Simulate cleanup time
			fmt.Printf("Worker %d cleaned up and exiting.
", id)
			return
		}
	}
}

func main() {
	fmt.Println("Application starting. Press Ctrl+C to initiate graceful shutdown.")

	// Create a context that can be cancelled
	ctx, cancel := context.WithCancel(context.Background())

	var wg sync.WaitGroup

	// Start multiple worker goroutines
	for i := 1; i <= 3; i++ {
		wg.Add(1)
		go workerGoroutine(ctx, i, &wg)
	}

	// Set up a channel to listen for OS signals (e.g., Ctrl+C)
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

	// Block until a signal is received
	sig := <-sigChan
	fmt.Printf("
Received OS signal: %s. Initiating graceful shutdown...
", sig)

	// Cancel the context, which will signal all goroutines to stop
	cancel()

	// Wait for all goroutines to finish their cleanup
	fmt.Println("Waiting for all workers to finish...")
	done := make(chan struct{})
	go func() {
		wg.Wait()
		close(done)
	}()

	// Set a timeout for graceful shutdown to prevent endless waiting
	select {
	case <-done:
		fmt.Println("All workers gracefully shut down.")
	case <-time.After(5 * time.Second):
		fmt.Println("Timeout for graceful shutdown exceeded. Force quitting.")
	}

	fmt.Println("Application exiting.")
}