infra

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Apr 13, 2026 License: Apache-2.0 Imports: 26 Imported by: 0

Documentation

Index

Constants

View Source
const EnvBifrostRole = "BIFROST_ROLE"

EnvBifrostRole variable used to identify worker processes.

View Source
const RoleWorker = "worker"

RoleWorker is the value of BIFROST_ROLE for worker processes.

Variables

View Source
var ErrMasterShuttingDown = errors.New("master is shutting down")

ErrMasterShuttingDown is returned when operations are attempted during shutdown.

View Source
var ErrRestartLimitExceeded = errors.New("restart limit exceeded: too many restarts in the last minute")

ErrRestartLimitExceeded is returned when the maximum restart rate is exceeded.

Functions

func GetControlSocketPath

func GetControlSocketPath() string

GetControlSocketPath returns the control socket path from environment. The path is base64 encoded to handle Abstract Namespace NUL bytes.

func InheritedListeners

func InheritedListeners() (map[string]*os.File, error)

InheritedListeners returns the listener FDs and their keys inherited from Master. Worker calls this on startup when UPGRADE=1.

func IsWorker

func IsWorker() bool

IsWorker returns true if the current process is a worker.

func NotifySystemdReady

func NotifySystemdReady()

NotifySystemdReady notifies systemd that the service is ready. This should be called after the Worker has confirmed it is ready. If not running under systemd (NOTIFY_SOCKET not set), this is a no-op.

func SetProcessName

func SetProcessName(name string) error

SetProcessName sets the process name visible in /proc/[pid]/comm. This name appears in tools like top, htop, and ps -o comm. Maximum 15 characters (Linux kernel limitation for PR_SET_NAME).

Types

type CommandRunner

type CommandRunner interface {
	Command(name string, arg ...string) *exec.Cmd
}

CommandRunner is an interface for creating exec.Cmd instances. It allows for dependency injection in testing scenarios.

type ControlMessage

type ControlMessage struct {
	// Type is the message type.
	Type MessageType `json:"type"`
	// WorkerPID is the PID of the Worker sending the message.
	WorkerPID int `json:"worker_pid,omitempty"`
	// Payload contains optional additional data.
	Payload []byte `json:"payload,omitempty"`
}

ControlMessage represents a message exchanged between Master and Worker.

type ControlPlane

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

ControlPlane provides Unix Domain Socket communication between Master and Worker. It uses Linux Abstract Namespace to avoid filesystem issues.

func NewControlPlane

func NewControlPlane(opts *ControlPlaneOptions) *ControlPlane

NewControlPlane creates a new ControlPlane instance. The Master calls this to create the UDS server.

Socket path priority:

  1. If opts.SocketPath is provided (from config.UpgradeSock), use it as file socket
  2. On Linux: use Abstract Namespace (no filesystem cleanup needed)
  3. On macOS/BSD: use file socket in /tmp

func (*ControlPlane) Accept

func (cp *ControlPlane) Accept(ctx context.Context) error

Accept accepts incoming Worker connections and handles messages. This blocks and should be run in a goroutine.

func (*ControlPlane) Close

func (cp *ControlPlane) Close() error

Close shuts down the ControlPlane.

func (*ControlPlane) Listen

func (cp *ControlPlane) Listen() error

Listen starts the UDS server (Master side). For file-based sockets, it cleans up any stale socket files first. Note: Go 1.12+ automatically sets CLOEXEC on all FDs, preventing leak to child processes.

func (*ControlPlane) ReceiveFDsFromConn

func (cp *ControlPlane) ReceiveFDsFromConn(conn net.Conn) ([]*os.File, error)

ReceiveFDsFromConn extracts FDs from the given connection using SCM_RIGHTS.

func (*ControlPlane) SendMessage

func (cp *ControlPlane) SendMessage(workerPID int, msg *ControlMessage) error

SendMessage sends a control message to a specific Worker.

func (*ControlPlane) SetFDHandler

func (cp *ControlPlane) SetFDHandler(handler func(fds []*os.File, keys []string))

SetFDHandler sets the callback for handling incoming FDs.

func (*ControlPlane) SetMessageHandler

func (cp *ControlPlane) SetMessageHandler(handler func(conn net.Conn, msg *ControlMessage))

SetMessageHandler sets the callback for handling incoming messages.

func (*ControlPlane) SocketPath

func (cp *ControlPlane) SocketPath() string

SocketPath returns the socket path used by this ControlPlane.

type ControlPlaneClient

type ControlPlaneClient interface {
	SendFDs(files []*os.File, keys []string) error
}

ControlPlaneClient defines the methods required by WorkerFDHandler to communicate with Master.

type ControlPlaneOptions

type ControlPlaneOptions struct {
	// SocketPath is the UDS path. If empty, uses Abstract Namespace.
	// Abstract Namespace format: "\x00bifrost-{pid}.sock"
	SocketPath string
}

ControlPlaneOptions contains configuration for the ControlPlane.

type EnvGetter

type EnvGetter func(string) string

EnvGetter is a function type for retrieving environment variables.

type FDHandler

type FDHandler interface {
	HandleFDRequest() error
}

FDHandler is an interface for handling file descriptor requests.

type FileOpener

type FileOpener func(name string) (*os.File, error)

FileOpener is a function type for opening files.

type KeepAlive

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

KeepAlive implements exponential backoff restart strategy for Worker processes. It prevents restart storms when a Worker has a fatal bug.

func NewKeepAlive

func NewKeepAlive(opts *KeepAliveOptions) *KeepAlive

NewKeepAlive creates a new KeepAlive instance.

func (*KeepAlive) CurrentBackoff

func (k *KeepAlive) CurrentBackoff() time.Duration

CurrentBackoff returns the current backoff duration.

func (*KeepAlive) RecordRestart

func (k *KeepAlive) RecordRestart()

RecordRestart records a restart event and updates backoff.

func (*KeepAlive) Reset

func (k *KeepAlive) Reset()

Reset resets the backoff to initial value. Called when Worker has been running stably for a period.

func (*KeepAlive) RestartsInLastMinute

func (k *KeepAlive) RestartsInLastMinute() int

RestartsInLastMinute returns the number of restarts in the last minute.

func (*KeepAlive) ShouldRestart

func (k *KeepAlive) ShouldRestart() (shouldRestart bool, backoffDuration time.Duration, err error)

ShouldRestart determines if a Worker should be restarted. Returns:

  • shouldRestart: true if restart is allowed
  • backoffDuration: how long to wait before restarting
  • error: non-nil if restart limit exceeded (Master should exit)

type KeepAliveOptions

type KeepAliveOptions struct {
	// InitialBackoff is the initial backoff duration (default: 1s).
	InitialBackoff time.Duration
	// MaxBackoff is the maximum backoff duration (default: 32s).
	MaxBackoff time.Duration
	// MaxRestartsPerMinute is the maximum restarts allowed per minute (default: 5).
	MaxRestartsPerMinute int
}

KeepAliveOptions contains configuration for the KeepAlive strategy.

func DefaultKeepAliveOptions

func DefaultKeepAliveOptions() *KeepAliveOptions

DefaultKeepAliveOptions returns the default KeepAlive configuration.

type ListenInfo

type ListenInfo struct {
	Listener net.Listener `json:"-"`
	Key      string       `json:"key"`
}

ListenInfo holds information about a network listener.

type ListenerOptions

type ListenerOptions struct {
	// Config is an optional net.ListenConfig for customizing the listener.
	Config *net.ListenConfig
	// Network specifies the network type (e.g., "tcp", "tcp4", "tcp6").
	Network string
	// Address is the address to listen on (e.g., ":8080", "localhost:3000").
	Address string
	// ProxyProtocol enables PROXY protocol support for the listener.
	ProxyProtocol bool
}

ListenerOptions contains configuration for creating a network listener.

type Master

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

Master manages the lifecycle of Worker processes. It provides PID stability for process managers (Systemd, Supervisor) and handles signal forwarding, hot reload, and worker monitoring.

func NewMaster

func NewMaster(opts *MasterOptions) *Master

NewMaster creates a new Master instance with the given options.

func (*Master) ControlPlane

func (m *Master) ControlPlane() *ControlPlane

ControlPlane returns the control plane instance.

func (*Master) Run

func (m *Master) Run(ctx context.Context) error

Run starts the Master's main loop. It spawns the initial Worker and waits for signals:

  • SIGHUP: triggers hot reload (spawn new Worker, gracefully stop old)
  • SIGTERM/SIGINT: triggers graceful shutdown of Worker and Master

This method blocks until shutdown is complete.

func (*Master) Shutdown

func (m *Master) Shutdown(_ context.Context) error

Shutdown gracefully stops the Master and its Worker.

func (*Master) State

func (m *Master) State() MasterState

State returns the current state of the Master.

func (*Master) WorkerPID

func (m *Master) WorkerPID() int

WorkerPID returns the PID of the current Worker process. Returns 0 if no Worker is running.

type MasterOptions

type MasterOptions struct {
	// ConfigPath is the path to the configuration file passed to Worker.
	ConfigPath string
	// Binary is the path to the executable (defaults to os.Args[0]).
	Binary string
	// Args are additional arguments passed to the Worker process.
	Args []string
	// GracefulTimeout is the maximum time to wait for Worker graceful shutdown.
	GracefulTimeout time.Duration
	// KeepAlive is the KeepAlive strategy configuration.
	KeepAlive *KeepAliveOptions
	// User to run worker as
	User string
	// Group to run worker as
	Group string
}

MasterOptions contains configuration for the Master process.

type MasterState

type MasterState int8

MasterState represents the current state of the Master process.

const (
	// MasterStateIdle indicates the master is idle and ready to spawn a worker.
	MasterStateIdle MasterState = iota
	// MasterStateRunning indicates the master has an active worker.
	MasterStateRunning
	// MasterStateReloading indicates a hot reload is in progress.
	MasterStateReloading
	// MasterStateShuttingDown indicates graceful shutdown is in progress.
	MasterStateShuttingDown
)

func (MasterState) String

func (s MasterState) String() string

String returns the string representation of MasterState.

type MessageType

type MessageType string

MessageType represents the type of control message sent via UDS.

const (
	// MessageTypeRegister is sent by Worker to Master upon startup.
	MessageTypeRegister MessageType = "register"
	// MessageTypeReady is sent by Worker to Master when ready to serve traffic.
	MessageTypeReady MessageType = "ready"
	// MessageTypeFDRequest is sent by Master to Worker to request listener FDs.
	MessageTypeFDRequest MessageType = "fd_request"
	// MessageTypeFDTransferStart is sent by Worker to Master on a DEDICATED connection to start FD transfer.
	MessageTypeFDTransferStart MessageType = "fd_transfer_start"
	// MessageTypeAck is sent by Master to Worker to acknowledge readiness for raw data.
	MessageTypeAck MessageType = "ack"
	// MessageTypeShutdown is sent by Master to Worker to request graceful shutdown.
	MessageTypeShutdown MessageType = "shutdown"
)

type Options

type Options struct {
	// QuitTimout is the maximum time to wait for the old process to terminate.
	QuitTimout time.Duration
}

Options contains configuration for the ZeroDownTime instance.

type ProcessFinder

type ProcessFinder interface {
	FindProcess(pid int) (process, error)
}

ProcessFinder is an interface for finding processes by PID. It allows for dependency injection in testing scenarios.

type State

type State int8

State represents the current state of the ZeroDownTime instance.

type WorkerControlPlane

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

WorkerControlPlane is the Worker-side control plane client.

func NewWorkerControlPlane

func NewWorkerControlPlane(socketPath string) *WorkerControlPlane

NewWorkerControlPlane creates a Worker-side control plane client.

func (*WorkerControlPlane) Close

func (wcp *WorkerControlPlane) Close() error

Close closes the connection to Master.

func (*WorkerControlPlane) Connect

func (wcp *WorkerControlPlane) Connect() error

Connect connects to the Master's ControlPlane.

func (*WorkerControlPlane) NotifyReady

func (wcp *WorkerControlPlane) NotifyReady() error

NotifyReady sends a ready message to Master.

func (*WorkerControlPlane) Register

func (wcp *WorkerControlPlane) Register() error

Register sends a register message to Master.

func (*WorkerControlPlane) SendFDs

func (wcp *WorkerControlPlane) SendFDs(files []*os.File, keys []string) error

SendFDs opens a dedicated connection to Master and sends listener FDs.

func (*WorkerControlPlane) Start

func (wcp *WorkerControlPlane) Start(ctx context.Context, fdHandler FDHandler) error

Start starts the worker control plane loop to handle messages from Master. It blocks until the context is canceled or the connection is closed.

type WorkerFDHandler

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

WorkerFDHandler handles FD requests from Master in Worker processes. It collects listener file descriptors and sends them to Master via ControlPlane.

func NewWorkerFDHandler

func NewWorkerFDHandler(wcp ControlPlaneClient) *WorkerFDHandler

NewWorkerFDHandler creates a new WorkerFDHandler.

func (*WorkerFDHandler) HandleFDRequest

func (h *WorkerFDHandler) HandleFDRequest() error

HandleFDRequest handles an FD request from Master. It collects all listener FDs and keys, then sends them via the control plane.

func (*WorkerFDHandler) ListenerCount

func (h *WorkerFDHandler) ListenerCount() int

ListenerCount returns the number of registered listeners.

func (*WorkerFDHandler) RegisterListener

func (h *WorkerFDHandler) RegisterListener(listener net.Listener, key string)

RegisterListener registers a listener for FD transfer. Call this for each listener the Worker creates or inherits.

type ZeroDownTime

type ZeroDownTime struct {
	QuitTimeout time.Duration
	// contains filtered or unexported fields
}

ZeroDownTime provides zero-downtime restart functionality for server processes. It manages PID files, upgrade sockets, and listener inheritance to enable seamless process upgrades without dropping connections.

func New

func New(opts Options) *ZeroDownTime

New creates a new ZeroDownTime instance with the given options. If QuitTimeout is not specified, it defaults to 10 seconds.

func (*ZeroDownTime) Close

func (z *ZeroDownTime) Close(_ context.Context) error

Close shuts down the ZeroDownTime instance by closing all listeners and stopping the upgrade waiting goroutine if active.

func (*ZeroDownTime) GetListeners

func (z *ZeroDownTime) GetListeners() []*ListenInfo

GetListeners returns the list of active listeners.

func (*ZeroDownTime) IsUpgraded

func (z *ZeroDownTime) IsUpgraded() bool

IsUpgraded returns true if this process was spawned as part of an upgrade. It checks for the presence of the UPGRADE environment variable.

func (*ZeroDownTime) IsWaiting

func (z *ZeroDownTime) IsWaiting() bool

IsWaiting returns true if the instance is in the waitingState.

func (*ZeroDownTime) Listener

func (z *ZeroDownTime) Listener(ctx context.Context, options *ListenerOptions) (net.Listener, error)

Listener returns a network listener for the given options. If this is an upgraded process, it attempts to inherit the listener from the parent process. Otherwise, it creates a new listener. The listener is cached for reuse.

func (*ZeroDownTime) WaitForUpgrade

func (z *ZeroDownTime) WaitForUpgrade(ctx context.Context) error

WaitForUpgrade blocks until a SIGHUP signal is received. When an upgrade is triggered, it spawns a new process with inherited file descriptors and waits for the Close method to be called before returning.

Jump to

Keyboard shortcuts

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