bootstrap

package
v0.1.5 Latest Latest
Warning

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

Go to latest
Published: Mar 1, 2026 License: MIT Imports: 12 Imported by: 0

README

bootstrap

Application bootstrap framework with lifecycle hooks, component registration, and startup summary.

Install

go get github.com/kbukum/gokit

Quick Start — Server

Use Run() for long-running services that block until a shutdown signal:

import (
    "context"
    gkconfig "github.com/kbukum/gokit/config"
    "github.com/kbukum/gokit/bootstrap"
)

func main() {
    var cfg MyConfig
    gkconfig.LoadConfig("my-service", &cfg)

    app, _ := bootstrap.NewApp(&cfg)
    app.OnConfigure(func(ctx context.Context, a *bootstrap.App[*MyConfig]) error {
        // Wire services, register routes, etc.
        return nil
    })

    app.Run(context.Background()) // blocks until SIGINT/SIGTERM
}

Quick Start — Task / CLI

Use RunTask() for CLI tools, batch jobs, and one-shot processes:

func main() {
    var cfg MyConfig
    gkconfig.LoadConfig("my-tool", &cfg)

    app, _ := bootstrap.NewApp(&cfg)
    app.OnConfigure(func(ctx context.Context, a *bootstrap.App[*MyConfig]) error {
        // Wire dependencies
        return nil
    })

    app.RunTask(context.Background(), func(ctx context.Context) error {
        return processData(ctx) // runs to completion, then shuts down
    })
}

Both modes share the same lifecycle: Initialize → OnStart → Configure → ReadyCheck → OnReady → (execute) → OnStop → Shutdown.

Key Types & Functions

Name Description
App[C] Generic application container with lifecycle management
NewApp[C]() Create app from typed config (must satisfy Config interface)
Run() Start long-running service with signal handling
RunTask() Execute a finite task with signal-based cancellation
OnConfigure() / OnStart() / OnReady() / OnStop() Lifecycle hooks
RegisterComponent() Add a managed component
WithLogger() / WithGracefulTimeout() / WithContainer() App options
Summary Tracks and displays startup summary

⬅ Back to main README

Documentation

Overview

Package bootstrap orchestrates application lifecycle for gokit services.

It provides typed configuration loading, component registration, dependency injection, and startup/shutdown hooks for rapid service initialization.

Two execution modes are supported:

  • Run: for long-running services that block until a shutdown signal
  • RunTask: for CLI tools and batch jobs that execute a finite task

Server Example

app, _ := bootstrap.NewApp(&cfg)
app.OnConfigure(func(ctx context.Context, a *bootstrap.App[*MyConfig]) error {
    // wire up services, routes, etc.
    return nil
})
app.Run(ctx) // blocks until SIGINT/SIGTERM

Task Example

app, _ := bootstrap.NewApp(&cfg)
app.RunTask(ctx, func(ctx context.Context) error {
    return processData(ctx) // runs to completion, then shuts down
})

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type App

type App[C Config] struct {
	Name       string
	Version    string
	Cfg        C
	Container  di.Container
	Components *component.Registry
	Logger     *logger.Logger
	Summary    *Summary
	// contains filtered or unexported fields
}

App represents a generic application with uniform lifecycle management. The type parameter C is the config type, which must satisfy the Config interface. Any struct embedding config.ServiceConfig automatically satisfies Config.

Example:

app, err := bootstrap.NewApp(&myConfig)
app.OnConfigure(func(ctx context.Context, a *bootstrap.App[*MyConfig]) error {
    // a.Cfg is *MyConfig — fully typed
    return nil
})
app.Run(context.Background())

func NewApp

func NewApp[C Config](cfg C, opts ...Option) (*App[C], error)

NewApp creates a new application instance from a typed config. It applies defaults, validates the config, and initializes the logger.

func (*App[C]) DisplaySummary

func (a *App[C]) DisplaySummary()

DisplaySummary prints the startup summary. It auto-collects infrastructure, routes, and health from the component registry and DI container.

func (*App[C]) OnConfigure

func (a *App[C]) OnConfigure(fn func(ctx context.Context, app *App[C]) error)

OnConfigure registers a callback to run during the configure phase. Use this to set up business-layer dependencies after infrastructure is started.

func (*App[C]) OnReady

func (a *App[C]) OnReady(hooks ...Hook)

OnReady registers a hook that runs after the application passes its ready check and is about to begin accepting traffic.

func (*App[C]) OnStart

func (a *App[C]) OnStart(hooks ...Hook)

OnStart registers a hook that runs after all components are started (Phase 1) but before the application is marked as ready.

func (*App[C]) OnStop

func (a *App[C]) OnStop(hooks ...Hook)

OnStop registers a hook that runs during graceful shutdown before components are stopped. Use this for cleanup tasks like draining connections or deregistering from service discovery.

func (*App[C]) ReadyCheck

func (a *App[C]) ReadyCheck(ctx context.Context) error

ReadyCheck verifies that all registered components are healthy.

func (*App[C]) RegisterComponent

func (a *App[C]) RegisterComponent(c component.Component) error

RegisterComponent adds a component to the application's registry.

func (*App[C]) Run

func (a *App[C]) Run(ctx context.Context) error

Run executes the full application lifecycle for long-running services: Initialize → OnStart hooks → Configure → ReadyCheck → OnReady hooks → Block on signal → OnStop hooks → Graceful Shutdown.

func (*App[C]) RunTask

func (a *App[C]) RunTask(ctx context.Context, task func(ctx context.Context) error) error

RunTask executes a finite task with the full bootstrap lifecycle. Unlike Run(), it does not block on shutdown signals — it runs the task function and gracefully shuts down when the task completes or the context is canceled (e.g., via SIGINT/SIGTERM).

Use RunTask for CLI tools, batch jobs, and one-shot processes that need the same bootstrap infrastructure (config, logger, components, hooks) but have a finite workflow instead of running forever.

Example:

app, _ := bootstrap.NewApp(&cfg)
app.RunTask(ctx, func(ctx context.Context) error {
    return processData(ctx)
})

func (*App[C]) Shutdown

func (a *App[C]) Shutdown(ctx context.Context) error

Shutdown performs graceful shutdown. Use when managing your own lifecycle.

func (*App[C]) WaitForSignal

func (a *App[C]) WaitForSignal(ctx context.Context) os.Signal

WaitForSignal blocks until an OS interrupt/term signal or context cancellation.

type BusinessComponentInfo

type BusinessComponentInfo struct {
	Name         string
	Type         string // "service", "repository", "handler"
	Status       string
	Dependencies []string
}

BusinessComponentInfo represents a business-layer component (service, repository, handler).

type ClientInfo

type ClientInfo struct {
	Name   string
	Target string
	Status string
	Type   string // "grpc", "http", etc.
}

ClientInfo represents an external client connection.

type ComponentStatus

type ComponentStatus struct {
	Name    string
	Status  string
	Healthy bool
}

ComponentStatus holds the tracked status of a component during bootstrap.

type Config

type Config interface {
	GetServiceConfig() *config.ServiceConfig
	ApplyDefaults()
	Validate() error
}

Config is the interface constraint for application configuration types. Any struct that embeds config.ServiceConfig (value embedding) automatically satisfies this interface via promoted methods.

Example:

type MyConfig struct {
    config.ServiceConfig `yaml:",inline" mapstructure:",squash"`
    Database database.Config `yaml:"database" mapstructure:"database"`
}

// MyConfig automatically satisfies Config via promoted methods.
app, err := bootstrap.NewApp[*MyConfig](&cfg)

type ConsumerInfo

type ConsumerInfo struct {
	Name   string
	Group  string
	Topic  string
	Status string
}

ConsumerInfo represents a message consumer (e.g. Kafka).

type Hook

type Hook func(ctx context.Context) error

Hook is a lifecycle callback that runs during application startup or shutdown. Services register hooks to perform setup/teardown without bootstrap knowing about specific infrastructure.

type InfrastructureInfo

type InfrastructureInfo struct {
	Name          string
	ComponentName string // Internal component name (for deduplication with ComponentStatus)
	Type          string // e.g. "database", "server", "kafka", "redis"
	Status        string
	Details       string
	Port          int
	Healthy       bool
}

InfrastructureInfo holds detailed infrastructure component information.

type Option

type Option func(*appOptions)

Option configures the App during creation. Options are non-generic so they can be used with any config type.

func WithContainer

func WithContainer(c di.Container) Option

WithContainer sets a custom DI container for the application.

func WithGracefulTimeout

func WithGracefulTimeout(d time.Duration) Option

WithGracefulTimeout sets the maximum duration for graceful shutdown.

func WithLogger

func WithLogger(l *logger.Logger) Option

WithLogger sets a custom logger for the application. If not set, the logger is auto-initialized from the config's Logging field.

type RouteInfo

type RouteInfo struct {
	Method  string
	Path    string
	Handler string
}

RouteInfo represents a registered HTTP route.

type Summary

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

Summary tracks and displays the application bootstrap process.

func NewSummary

func NewSummary(serviceName, version string) *Summary

NewSummary creates a new bootstrap summary tracker.

func (*Summary) DisplaySummary

func (s *Summary) DisplaySummary(registry *component.Registry, container di.Container, log *logger.Logger)

DisplaySummary prints the bootstrap summary. It auto-collects infrastructure, routes, and health from the component registry and DI registrations from the container. Manual Track* calls are only needed for non-component items (e.g., auth config).

func (*Summary) SetStartupDuration

func (s *Summary) SetStartupDuration(d time.Duration)

SetStartupDuration records the total startup time.

func (*Summary) TrackBusinessComponent

func (s *Summary) TrackBusinessComponent(name, componentType, status string, dependencies []string)

trackInfrastructureWithComponent is like TrackInfrastructure but also records the internal component name for deduplication with the Components section. TrackBusinessComponent records a business-layer component.

func (*Summary) TrackClient

func (s *Summary) TrackClient(name, target, status, clientType string)

TrackClient records an external client connection.

func (*Summary) TrackComponent

func (s *Summary) TrackComponent(name, status string, healthy bool)

TrackComponent adds a component's bootstrap status to the summary.

func (*Summary) TrackConsumer

func (s *Summary) TrackConsumer(name, group, topic, status string)

TrackConsumer records a message consumer.

func (*Summary) TrackInfrastructure

func (s *Summary) TrackInfrastructure(name, componentType, status, details string, port int, healthy bool)

TrackInfrastructure adds an infrastructure component with detailed metadata. For non-component infrastructure (e.g., auth config), componentName can be empty.

func (*Summary) TrackRoute

func (s *Summary) TrackRoute(method, path, handler string)

TrackRoute records an HTTP route.

Jump to

Keyboard shortcuts

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