Documentation
¶
Overview ¶
Package gscore is the framework-agnostic engine behind the gsfiber (Fiber v2) and gsfiberv3 (Fiber v3) graceful-shutdown adapters. It orchestrates the shutdown lifecycle: signal capture, pre-stop delay, readiness flip, HTTP drain, ordered hooks, GORM pool close, and a force-kill ceiling.
The public adapter packages are thin wrappers that translate a framework's Shutdown method into the generic Shutdowner interface accepted here.
Index ¶
- type Config
- type Hook
- type Logger
- type Manager
- func (m *Manager) AddHook(h Hook)
- func (m *Manager) IsReady() bool
- func (m *Manager) ListenAndWait() error
- func (m *Manager) RegisterCloser(name string, phase Phase, timeout time.Duration, ...)
- func (m *Manager) RegisterDB(db *gorm.DB)
- func (m *Manager) RegisterServer(s Shutdowner)
- func (m *Manager) RootContext() context.Context
- func (m *Manager) SetReady(v bool)
- func (m *Manager) Trigger()
- func (m *Manager) Wait() error
- type Phase
- type Shutdowner
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Signals that trigger Start to return and shutdown to begin. Defaults
// to SIGINT + SIGTERM when nil.
Signals []os.Signal
// PreStopDelay is a sleep injected after a signal is received but
// before any phase runs. Gives kube-proxy / load balancers time to
// observe the failing readiness probe and stop routing new traffic.
// Zero disables the delay.
PreStopDelay time.Duration
// Per-phase timeouts. Zero means "use ForceKillAfter as a soft cap"
// (i.e. no per-phase deadline beyond the global one).
DrainTimeout time.Duration
HookTimeout time.Duration // applied per phase, not per hook
DBCloseTimeout time.Duration
// ForceKillAfter bounds the whole shutdown sequence. When exceeded,
// the Manager logs an error and calls os.Exit(1). Zero disables.
ForceKillAfter time.Duration
// Logger receives per-phase events. Nil = silent.
Logger Logger
// OnHookError is invoked whenever a hook returns a non-nil error.
// It does not stop the sequence. Nil = errors only go to the logger.
OnHookError func(name string, phase Phase, err error)
}
Config configures a Manager. All durations are independent; the global ForceKillAfter bounds the entire sequence as a hard ceiling.
func (Config) WithDefaults ¶
WithDefaults returns cfg with zero-valued fields filled in.
type Hook ¶
Hook is a user-registered shutdown action. Lower Priority runs first within the same phase; equal priorities run in registration order.
type Logger ¶
type Logger interface {
Info(msg string, kv ...any)
Warn(msg string, kv ...any)
Error(msg string, kv ...any)
}
Logger is the structured-logging surface the Manager calls during the shutdown sequence. Implementations should be safe for concurrent use.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager coordinates the shutdown sequence. It is safe to construct once at boot and share across goroutines; Trigger and Wait may be called concurrently.
func New ¶
New constructs a Manager. The returned Manager's RootContext is live until Trigger fires.
func (*Manager) IsReady ¶
IsReady reports the readiness flag. It is true at construction and flipped to false the moment a shutdown signal is observed. Kubernetes readiness probes should reflect this value.
func (*Manager) ListenAndWait ¶
ListenAndWait blocks until one of cfg.Signals is received OR Trigger is called from elsewhere, then runs the shutdown sequence and returns. Typical use is `defer mgr.ListenAndWait()` at the end of main, after starting the server in a goroutine.
func (*Manager) RegisterCloser ¶
func (m *Manager) RegisterCloser(name string, phase Phase, timeout time.Duration, fn func(ctx context.Context) error)
RegisterCloser registers a generic resource close action for the given phase. Closers run sequentially within the phase (after that phase's hooks), each bounded by its own timeout — so a slow Redis client cannot starve a fast Kafka producer that comes after it.
Typical placements:
- PhasePostDrain: outbound clients that the handler chain used (HTTP clients, gRPC connections) and that the DB close does not depend on.
- PhasePostDB: Redis / cache / search clients consumed during DB commit-time callbacks (e.g. txctx.OnCommit). Closing them only after PhaseDB guarantees those callbacks completed.
timeout=0 falls back to Config.HookTimeout. Empty name is auto-filled. A nil fn is a no-op (the entry is dropped).
func (*Manager) RegisterDB ¶
RegisterDB adds a GORM DB whose underlying *sql.DB will be Close()'d during PhaseDB. Multiple DBs are closed sequentially in registration order.
func (*Manager) RegisterServer ¶
func (m *Manager) RegisterServer(s Shutdowner)
RegisterServer adds an HTTP-like server to be drained during PhaseDrain. Multiple servers are drained concurrently with a shared deadline.
func (*Manager) RootContext ¶
RootContext returns a context.Context that is cancelled the moment the shutdown sequence begins. Outbound HTTP clients, workers, and any long-running operation should derive their context from this so they observe shutdown via ctx.Done().
func (*Manager) SetReady ¶
SetReady forces the readiness flag. Useful for tests or for marking "not ready" before the process is even started.
type Phase ¶
type Phase int
Phase identifies a stage of the shutdown sequence. Hooks are grouped by phase; phases run sequentially in the order below.
const ( // PhasePreStop runs first, before HTTP drain. Use it for actions that // must happen while the server is still serving (e.g. flushing an // in-memory queue back to a durable store). PhasePreStop Phase = iota // PhaseDrain runs the HTTP server drain. PhaseDrain // PhasePostDrain runs after the HTTP server is fully drained but before // the database pool is closed. Most outbound-call cleanups belong here. PhasePostDrain // PhaseDB runs the GORM pool close. PhaseDB // PhasePostDB runs last, after the database is closed. Use it for // resources that do not depend on the DB (Kafka producers, log // flushers, metric exporters). PhasePostDB )
type Shutdowner ¶
type Shutdowner interface {
// ShutdownWithContext must stop accepting new connections and wait for
// in-flight requests to finish, returning when ctx is done or all
// requests drained.
ShutdownWithContext(ctx context.Context) error
}
Shutdowner is the minimal contract an HTTP server (or anything similar) must satisfy to be drained by the Manager. Both Fiber v2 (*fiber.App) and Fiber v3 (*fiber.App) implement Shutdown / ShutdownWithContext directly; the adapter packages adapt the exact signature.