service

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2025 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package service provides abstractions for microservice lifecycle management. It supports unified lifecycle for HTTP and gRPC servers with graceful shutdown, signal handling, and cleanup hooks.

Example usage:

// Create HTTP service
httpSvc := service.NewHTTPService("my-service", ":8080", handler,
    service.WithReadTimeout(10*time.Second),
    service.WithShutdownTimeout(30*time.Second),
)

// Start service
if err := httpSvc.Start(ctx); err != nil {
    log.Fatal(err)
}

// Wait for shutdown signal
service.WaitForShutdown(ctx, httpSvc)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func WaitForShutdown

func WaitForShutdown(ctx context.Context, services ...Service)

WaitForShutdown blocks until a shutdown signal is received, then gracefully stops the provided services. It handles SIGINT and SIGTERM by default.

Services are stopped in the order provided. If a service fails to stop within the timeout, the error is logged but shutdown continues for remaining services.

Example:

httpSvc := service.NewHTTPService("api", ":8080", handler)
if err := httpSvc.Start(ctx); err != nil {
    log.Fatal(err)
}

// Block until shutdown signal
service.WaitForShutdown(ctx, httpSvc)

func WaitForShutdownWithConfig

func WaitForShutdownWithConfig(ctx context.Context, cfg ShutdownConfig, services ...Service)

WaitForShutdownWithConfig is like WaitForShutdown but accepts custom shutdown configuration.

Example:

cfg := service.ShutdownConfig{
    Timeout: 60 * time.Second,
    Signals: []os.Signal{syscall.SIGTERM},
}
service.WaitForShutdownWithConfig(ctx, cfg, httpSvc, grpcSvc)

func WithShutdownHandler

func WithShutdownHandler(ctx context.Context, svc Service) error

WithShutdownHandler wraps a service with automatic signal-based shutdown. It starts the service and blocks until a shutdown signal is received.

Example:

svc := service.NewHTTPService("api", ":8080", handler)
if err := service.WithShutdownHandler(ctx, svc); err != nil {
    log.Fatal(err)
}

Types

type Bootstrap

type Bootstrap struct {
	Config         *config.Config
	Logger         *logging.Logger
	TracerProvider *sdktrace.TracerProvider
	// contains filtered or unexported fields
}

Bootstrap represents initialized infrastructure components. It provides convenient access to all observability components.

func NewBootstrap

func NewBootstrap(ctx context.Context, cfg *config.Config, opts ...BootstrapOption) (*Bootstrap, error)

NewBootstrap initializes all observability components from configuration. It creates logger, metrics, and tracing infrastructure in the correct order with appropriate error handling.

Example:

cfg := config.MustLoad("config.yaml", "MYAPP")
bootstrap, err := service.NewBootstrap(ctx, cfg)
if err != nil {
    log.Fatal(err)
}
defer bootstrap.Cleanup(ctx)

// Use bootstrap.Logger, bootstrap.Tracer, etc.

func (*Bootstrap) AddCleanup

func (b *Bootstrap) AddCleanup(fn func(context.Context) error)

AddCleanup adds a cleanup function to be executed during Cleanup. Cleanup functions are executed in reverse order (LIFO).

Example:

bootstrap.AddCleanup(func(ctx context.Context) error {
    return db.Close()
})

func (*Bootstrap) Cleanup

func (b *Bootstrap) Cleanup(ctx context.Context) error

Cleanup shuts down all initialized infrastructure components. It executes cleanup functions in reverse order (LIFO) to ensure proper dependency cleanup. Always defer this after creating Bootstrap.

type BootstrapOption

type BootstrapOption func(*bootstrapConfig)

BootstrapOption is a functional option for configuring bootstrap behavior.

func WithoutLogger

func WithoutLogger() BootstrapOption

WithoutLogger disables logger initialization during bootstrap. This is rarely needed but can be useful for testing.

func WithoutMetrics

func WithoutMetrics() BootstrapOption

WithoutMetrics disables metrics initialization during bootstrap.

func WithoutTracing

func WithoutTracing() BootstrapOption

WithoutTracing disables tracing initialization during bootstrap.

type CleanupFunc

type CleanupFunc func(context.Context) error

CleanupFunc represents a cleanup function to be executed during shutdown.

type CleanupHandler

type CleanupHandler struct {
	// contains filtered or unexported fields
}

CleanupHandler manages cleanup functions that should be executed during shutdown. Cleanup functions are executed in LIFO order (last registered, first executed).

func NewCleanupHandler

func NewCleanupHandler() *CleanupHandler

NewCleanupHandler creates a new cleanup handler.

func (*CleanupHandler) Execute

func (h *CleanupHandler) Execute(ctx context.Context) error

Execute runs all registered cleanup functions in reverse order (LIFO). It continues executing cleanup functions even if some fail, collecting all errors. Returns the first error encountered, but logs all errors.

func (*CleanupHandler) Register

func (h *CleanupHandler) Register(fn CleanupFunc)

Register adds a cleanup function to be executed during shutdown. Cleanup functions are executed in reverse order (LIFO).

Example:

cleanup := service.NewCleanupHandler()
cleanup.Register(func(ctx context.Context) error {
    return db.Close()
})
cleanup.Register(func(ctx context.Context) error {
    return cache.Close()
})
defer cleanup.Execute(ctx)

type GRPCService

type GRPCService struct {
	// contains filtered or unexported fields
}

GRPCService implements the Service interface for gRPC servers. It manages the lifecycle of a gRPC server with graceful shutdown.

func NewGRPCService

func NewGRPCService(name, addr string, registerFunc func(*grpc.Server), opts ...GRPCServiceOption) *GRPCService

NewGRPCService creates a new gRPC service with the provided configuration. The registerFunc is called with the gRPC server to register service implementations.

Example:

svc := service.NewGRPCService("grpc-server", ":9090",
    func(s *grpc.Server) {
        pb.RegisterMyServiceServer(s, &myServiceImpl{})
    },
    service.WithReflection(true),
    service.WithGRPCShutdownTimeout(30*time.Second),
)

func NewGRPCServiceWithServer

func NewGRPCServiceWithServer(name, addr string, server *grpc.Server, opts ...GRPCServiceOption) *GRPCService

NewGRPCServiceWithServer creates a new gRPC service using an existing gRPC server. This is useful when you need to configure the gRPC server with specific interceptors or other options before creating the service.

Example:

grpcServer := grpc.NewServer(
    grpc.UnaryInterceptor(myInterceptor),
)
svc := service.NewGRPCServiceWithServer("grpc-server", ":9090", grpcServer,
    service.WithGRPCShutdownTimeout(30*time.Second),
)

func (*GRPCService) Health

func (s *GRPCService) Health() error

Health checks if the gRPC server is running. Returns nil if healthy, error if not running.

func (*GRPCService) Name

func (s *GRPCService) Name() string

Name returns the service name.

func (*GRPCService) Server

func (s *GRPCService) Server() *grpc.Server

Server returns the underlying gRPC server. This is useful for testing or advanced configuration.

func (*GRPCService) Start

func (s *GRPCService) Start(ctx context.Context) error

Start starts the gRPC server and blocks until the server is listening. It returns an error if the server fails to start.

func (*GRPCService) Stop

func (s *GRPCService) Stop(ctx context.Context) error

Stop gracefully stops the gRPC server, waiting for in-flight RPCs to complete. It respects the context deadline for shutdown timeout.

type GRPCServiceOption

type GRPCServiceOption func(*GRPCService)

GRPCServiceOption is a functional option for configuring a GRPCService.

func WithGRPCShutdownTimeout

func WithGRPCShutdownTimeout(timeout time.Duration) GRPCServiceOption

WithGRPCShutdownTimeout sets the graceful shutdown timeout for the gRPC server.

func WithReflection

func WithReflection(enable bool) GRPCServiceOption

WithReflection enables gRPC reflection for the server. This allows tools like grpcurl to introspect the service.

type HTTPService

type HTTPService struct {
	// contains filtered or unexported fields
}

HTTPService implements the Service interface for HTTP servers. It manages the lifecycle of an HTTP server with graceful shutdown.

func NewHTTPService

func NewHTTPService(name, addr string, handler http.Handler, opts ...HTTPServiceOption) *HTTPService

NewHTTPService creates a new HTTP service with the provided configuration. The handler will be invoked for all incoming HTTP requests.

Example:

mux := http.NewServeMux()
mux.HandleFunc("/health", healthHandler)
svc := service.NewHTTPService("api-server", ":8080", mux,
    service.WithShutdownTimeout(30*time.Second),
)

func (*HTTPService) Health

func (s *HTTPService) Health() error

Health checks if the HTTP server is running. Returns nil if healthy, error if not running.

func (*HTTPService) Name

func (s *HTTPService) Name() string

Name returns the service name.

func (*HTTPService) Start

func (s *HTTPService) Start(ctx context.Context) error

Start starts the HTTP server and blocks until the server is listening. It returns an error if the server fails to start.

func (*HTTPService) Stop

func (s *HTTPService) Stop(ctx context.Context) error

Stop gracefully stops the HTTP server, waiting for in-flight requests to complete. It respects the context deadline for shutdown timeout.

type HTTPServiceOption

type HTTPServiceOption func(*HTTPService)

HTTPServiceOption is a functional option for configuring an HTTPService.

func WithMaxHeaderBytes

func WithMaxHeaderBytes(bytes int) HTTPServiceOption

WithMaxHeaderBytes sets the maximum header bytes for the HTTP server.

func WithReadTimeout

func WithReadTimeout(timeout time.Duration) HTTPServiceOption

WithReadTimeout sets the HTTP server read timeout.

func WithShutdownTimeout

func WithShutdownTimeout(timeout time.Duration) HTTPServiceOption

WithShutdownTimeout sets the graceful shutdown timeout.

func WithWriteTimeout

func WithWriteTimeout(timeout time.Duration) HTTPServiceOption

WithWriteTimeout sets the HTTP server write timeout.

type Service

type Service interface {
	// Start starts the service and blocks until the service is ready.
	// Returns an error if the service fails to start.
	// The context can be used to cancel startup if needed.
	Start(ctx context.Context) error

	// Stop gracefully stops the service, waiting for in-flight requests to complete.
	// Returns an error if the service fails to stop within the timeout.
	// The context deadline determines how long to wait for graceful shutdown.
	Stop(ctx context.Context) error

	// Name returns the name of the service for logging and identification.
	Name() string

	// Health performs a health check on the service.
	// Returns nil if the service is healthy, or an error describing the problem.
	Health() error
}

Service represents a service that can be started, stopped, and health-checked. It provides a unified interface for HTTP and gRPC servers.

type ShutdownConfig

type ShutdownConfig struct {
	// Timeout is the maximum time to wait for graceful shutdown.
	// After this timeout, services are forcefully stopped.
	Timeout time.Duration

	// Signals is the list of OS signals that trigger shutdown.
	// If empty, defaults to SIGINT and SIGTERM.
	Signals []os.Signal
}

ShutdownConfig configures graceful shutdown behavior.

func DefaultShutdownConfig

func DefaultShutdownConfig() ShutdownConfig

DefaultShutdownConfig returns sensible default shutdown configuration.

Jump to

Keyboard shortcuts

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