shutdown

package
v1.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 28, 2025 License: MIT Imports: 8 Imported by: 0

README

Shutdown

Overview

The Shutdown component provides functionality for graceful application shutdown in Go applications. It handles OS signals (SIGINT, SIGTERM, SIGHUP) and context cancellation to trigger controlled shutdown processes, ensuring that resources are properly released and in-flight operations can complete before the application exits.

Features

  • Signal Handling: Automatically detect and respond to OS termination signals
  • Context Cancellation: Support for context-based shutdown initiation
  • Timeout Management: Apply configurable timeouts to prevent shutdown processes from hanging
  • Multiple Signal Handling: Force immediate exit if a second signal is received during shutdown
  • Error Propagation: Capture and return errors that occur during the shutdown process
  • Programmatic Shutdown: Trigger shutdown programmatically in addition to signal-based shutdown
  • Logging Integration: Comprehensive logging of the shutdown process

Installation

go get github.com/abitofhelp/servicelib/shutdown

Quick Start

package main

import (
    "context"
    "fmt"
    "log"
    "net/http"
    "time"
    
    "github.com/abitofhelp/servicelib/logging"
    "github.com/abitofhelp/servicelib/shutdown"
    "go.uber.org/zap"
)

func main() {
    // Create a logger
    logger, _ := zap.NewProduction()
    contextLogger := logging.NewContextLogger(logger)
    
    // Create an HTTP server
    server := &http.Server{
        Addr:    ":8080",
        Handler: http.DefaultServeMux,
    }
    
    // Define a shutdown function
    shutdownFunc := func() error {
        // Create a timeout for server shutdown
        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        defer cancel()
        
        fmt.Println("Shutting down HTTP server...")
        return server.Shutdown(ctx)
    }
    
    // Set up graceful shutdown
    ctx := context.Background()
    cancel, errCh := shutdown.SetupGracefulShutdown(ctx, contextLogger, shutdownFunc)
    defer cancel() // Ensure cancellation in case of early return
    
    // Start the HTTP server
    go func() {
        fmt.Println("Starting HTTP server on :8080")
        if err := server.ListenAndServe(); err != http.ErrServerClosed {
            log.Fatalf("HTTP server error: %v", err)
        }
    }()
    
    // Wait for shutdown to complete
    if err := <-errCh; err != nil {
        log.Fatalf("Shutdown error: %v", err)
    }
    
    fmt.Println("Application has shut down gracefully")
}

API Documentation

Key Functions
GracefulShutdown

Waits for termination signals and calls the provided shutdown function.

func GracefulShutdown(ctx context.Context, logger *logging.ContextLogger, shutdownFunc func() error) error

This function handles OS signals (SIGINT, SIGTERM, SIGHUP) and context cancellation to trigger graceful shutdown. It also handles multiple signals, forcing exit if a second signal is received during shutdown. A default timeout of 30 seconds is applied to the shutdown function to prevent hanging.

SetupGracefulShutdown

Sets up a goroutine that will handle graceful shutdown.

func SetupGracefulShutdown(ctx context.Context, logger *logging.ContextLogger, shutdownFunc func() error) (context.CancelFunc, <-chan error)

This function creates a new context with cancellation and starts a background goroutine that calls GracefulShutdown. It returns a cancel function that can be called to trigger shutdown programmatically and a channel that will receive any error that occurs during shutdown.

Examples

For complete, runnable examples, see the following directories in the EXAMPLES directory:

Best Practices

  1. Define Clear Shutdown Order: Close resources in the reverse order they were created
  2. Set Appropriate Timeouts: Configure timeouts based on expected shutdown durations
  3. Handle In-Flight Operations: Allow in-flight operations to complete before shutting down
  4. Log Shutdown Progress: Log the start and completion of each shutdown step
  5. Propagate Errors: Return errors from the shutdown function to help diagnose issues

Troubleshooting

Common Issues
Shutdown Hanging

If your application is hanging during shutdown:

  • Check if any goroutines are deadlocked
  • Ensure all resources have proper close methods
  • Verify that timeouts are set appropriately
  • Look for infinite loops or blocking operations in the shutdown function
Premature Exit

If your application exits before completing the shutdown process:

  • Ensure you're waiting for the error channel from SetupGracefulShutdown
  • Check if any panics are occurring during shutdown
  • Verify that the shutdown function is properly implemented
  • Signal - Lower-level signal handling utilities
  • Context - Context utilities for timeout and cancellation
  • Logging - Logging integration for shutdown events
  • Errors - Error handling for shutdown errors

Contributing

Contributions to this component are welcome! Please see the Contributing Guide for more information.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Overview

Package shutdown provides functionality for graceful application shutdown.

This package implements a robust system for handling application termination, ensuring that resources are properly released and in-flight operations are completed before the application exits. It handles OS signals (SIGINT, SIGTERM, SIGHUP) and context cancellation to trigger graceful shutdown.

Proper shutdown handling is critical for production applications to prevent:

  • Data loss from incomplete operations
  • Resource leaks from unclosed connections
  • Inconsistent state from abrupt termination
  • Service disruption for users during deployments

Key features:

  • Signal-based shutdown handling (SIGINT, SIGTERM, SIGHUP)
  • Context-based shutdown initiation for programmatic control
  • Timeout management to prevent hanging during shutdown
  • Multiple signal handling with forced exit on second signal
  • Comprehensive logging of shutdown events
  • Error propagation from shutdown operations

The package provides two main functions:

  • GracefulShutdown: Blocks until shutdown is triggered, then executes cleanup
  • SetupGracefulShutdown: Sets up background shutdown handling without blocking

Example usage with GracefulShutdown (blocking approach):

func main() {
    // Initialize application components
    logger := logging.NewContextLogger(zapLogger)
    server := startServer()
    db := connectToDatabase()

    // Define shutdown function
    shutdownFunc := func() error {
        // Close resources in reverse order of creation
        serverErr := server.Shutdown(context.Background())
        dbErr := db.Close()

        // Return combined error if any
        if serverErr != nil || dbErr != nil {
            return fmt.Errorf("shutdown errors: server=%v, db=%v", serverErr, dbErr)
        }
        return nil
    }

    // Wait for shutdown signal and execute cleanup
    if err := shutdown.GracefulShutdown(context.Background(), logger, shutdownFunc); err != nil {
        logger.Error(context.Background(), "Shutdown completed with errors", zap.Error(err))
        os.Exit(1)
    }
}

Example usage with SetupGracefulShutdown (non-blocking approach):

func main() {
    // Initialize application components
    logger := logging.NewContextLogger(zapLogger)
    server := startServer()
    db := connectToDatabase()

    // Define shutdown function
    shutdownFunc := func() error {
        // Close resources in reverse order of creation
        serverErr := server.Shutdown(context.Background())
        dbErr := db.Close()

        // Return combined error if any
        if serverErr != nil || dbErr != nil {
            return fmt.Errorf("shutdown errors: server=%v, db=%v", serverErr, dbErr)
        }
        return nil
    }

    // Set up graceful shutdown in the background
    cancel, errCh := shutdown.SetupGracefulShutdown(context.Background(), logger, shutdownFunc)
    defer cancel() // Ensure shutdown is triggered if main exits

    // Continue with application logic
    // ...

    // Optionally wait for shutdown to complete and check for errors
    if err := <-errCh; err != nil {
        logger.Error(context.Background(), "Shutdown completed with errors", zap.Error(err))
        os.Exit(1)
    }
}

The package is designed to be used at the application's entry point (main function) to ensure proper resource cleanup during termination.

Package shutdown provides functionality for graceful application shutdown.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GracefulShutdown

func GracefulShutdown(ctx context.Context, logger *logging.ContextLogger, shutdownFunc func() error) error

GracefulShutdown waits for termination signals and calls the provided shutdown function. It handles OS signals (SIGINT, SIGTERM, SIGHUP) and context cancellation to trigger graceful shutdown. It also handles multiple signals, forcing exit if a second signal is received during shutdown. A default timeout of 30 seconds is applied to the shutdown function to prevent hanging.

Parameters:

  • ctx: Context that can be cancelled to trigger shutdown
  • logger: Logger for recording shutdown events
  • shutdownFunc: Function to execute during shutdown

Returns:

  • The error from the shutdown function, if any

func SetupGracefulShutdown

func SetupGracefulShutdown(ctx context.Context, logger *logging.ContextLogger, shutdownFunc func() error) (context.CancelFunc, <-chan error)

SetupGracefulShutdown sets up a goroutine that will handle graceful shutdown. It creates a new context with cancellation and starts a background goroutine that calls GracefulShutdown. This allows for both signal-based and programmatic shutdown initiation.

Parameters:

  • ctx: Parent context for the shutdown context
  • logger: Logger for recording shutdown events
  • shutdownFunc: Function to execute during shutdown

Returns:

  • A cancel function that can be called to trigger shutdown programmatically
  • A channel that will receive any error that occurs during shutdown

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL