Help us shape the future of Go! Take the 2026 Go Developer Survey

foundation

package
v0.5.3 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package foundation owns application assembly and lifecycle contracts shared by all Foundry kernels. It does not depend on concrete infrastructure drivers.

Index

Constants

View Source
const DefaultShutdownTimeout = 25 * time.Second

DefaultShutdownTimeout is the whole shutdown budget: stop delay, kernel drain and every cleanup. It exceeds the default HTTP shutdown grace and fits a common 30-second orchestrator termination period. It bounds waits, not the lifetime of a goroutine ignoring cancellation; such work remains tracked until it exits.

Variables

This section is empty.

Functions

func Contribute

func Contribute[T any](r *Registrar, collection Collection[T], id string, create func(Resolver) (T, error)) error

Contribute registers an ordinary typed factory in a named collection. The semantic ID and scope form an unambiguous key for duplicate/override checks.

func ContributeAs

func ContributeAs[S, T any](r *Registrar, collection Collection[T], id string, create func(Resolver) (T, error)) error

ContributeAs preserves schema S at an erased feature boundary T, for example a job payload and jobs.Declaration. An explicit override must retain both T and S. Feature helpers infer S from their existing typed declarations.

func Contributions

func Contributions[T any](r Resolver, collection Collection[T]) ([]T, error)

Contributions constructs only members of this exact collection in dependency and registration order. Results are independent slices; object ownership follows the same rules as Resolve. Constructors must remain pure.

func Factory

func Factory[T any](r *Registrar, key Key[T], create func(Resolver) (T, error)) error

Factory registers an explicit constructor. Constructors run once, eagerly, after registration freezes. Missing/cyclic dependencies fail Build before any provider boots. Panics and Goexit report fault.Panicked and expire the resolver. Reflection records only the declared type; it never autowires.

func Provide

func Provide[T any](r *Registrar, key Key[T], value T) error

Provide binds an existing value. Resources requiring cleanup should be acquired during Boot and registered with Runtime.OnShutdown.

func Resolve

func Resolve[T any](r Resolver, key Key[T]) (T, error)

Resolve obtains a typed service during construction. The value type is inferred from its key; application code does not perform type assertions.

func ResolveAll

func ResolveAll[T any](r Resolver) ([]T, error)

ResolveAll collects services registered with exactly the declared type T, in provider/registration order. Use it during construction to assemble explicit feature contributions, then inject the constructed feature into domain code. It does not discover assignable concrete types or autowire dependencies. An empty collection is valid. The returned slice is independent; its service values retain their usual application lifetime and concurrency ownership.

Types

type App

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

App owns provider startup, a selected kernel and reverse-order shutdown. Services are available after Build; external resources become ready at Start.

func (*App) Done

func (a *App) Done() <-chan struct{}

Done returns the application's completion channel.

func (*App) Inspect

func (a *App) Inspect() Inspection

Inspect returns an inspection snapshot.

func (*App) Logger

func (a *App) Logger() *slog.Logger

Logger returns the configured application logger.

func (*App) Maintenance

func (a *App) Maintenance() *maintenance.Gate

Maintenance returns the application's admission gate. It exists whether or not observability is configured and is carried by every runtime context.

func (*App) Observability

func (a *App) Observability() *observability.Recorder

Observability returns the configured observability recorder.

func (*App) PendingTasks

func (a *App) PendingTasks() []string

PendingTasks reports currently active, provider-qualified task names.

func (*App) Run

func (a *App) Run(ctx context.Context, kind KernelKind) error

Run starts providers and executes one registered runtime kernel. Completion, cancellation or a critical task failure initiates shutdown automatically. Cancelling ctx is a graceful stop: a service kernel (HTTP, worker, scheduler, WebSocket) that drains cooperatively and whose shutdown completes cleanly returns nil. A CLI kernel is one-shot, so its interruption stays an error. Each failure is reported once. Run waits for shutdown up to the application shutdown budget, which covers the stop delay, kernel drain and every cleanup.

func (*App) RunKernels

func (a *App) RunKernels(ctx context.Context, kinds ...KernelKind) error

RunKernels runs several service kernels in one process, for example HTTP and a worker, sharing one provider lifetime. The first kernel to finish, a caller cancellation or a critical task failure stops every kernel. The CLI kernel is one-shot and must run alone. Kinds must be distinct and registered.

func (*App) Services

func (a *App) Services() *Services

Services returns the application's service registry.

func (*App) Shutdown

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

Shutdown requests cancellation and waits up to the caller's deadline. A timeout does not kill Go goroutines or close their dependencies underneath them. Cleanup continues, and callers can wait again on Shutdown or Done. The configured stop delay applies to the first request on a running app.

func (*App) ShutdownTimeout

func (a *App) ShutdownTimeout() time.Duration

ShutdownTimeout returns the configured shutdown timeout.

func (*App) Start

func (a *App) Start(ctx context.Context) error

Start boots the application once. The first caller's context owns its lifetime: its cancellation requests shutdown, including the configured stop delay. Concurrent callers wait for the same startup result using their own deadline.

func (*App) State

func (a *App) State() State

State returns the lifecycle state under the application mutex.

func (*App) StopDelay

func (a *App) StopDelay() time.Duration

StopDelay returns the configured stop delay.

type Booter

type Booter interface {
	// Boot boots the provider with its runtime and context.
	Boot(context.Context, *Runtime) error
}

Booter optionally acquires resources after all services have been resolved. Register each acquired resource with Runtime.OnShutdown before continuing so partial startup failures are cleaned up by the framework.

type Builder

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

Builder is a single-use application composition. Build freezes registration; create a fresh builder through your bootstrap function for each application.

func NewBuilder

func NewBuilder(options ...Option) *Builder

NewBuilder constructs independent foundation state for explicit providers. Applications can use root foundry.New for this same direct assembly path, or application.New for configured service and HTTP assembly. Feature and testing packages use NewBuilder without depending on either application entry point.

func (*Builder) Build

func (b *Builder) Build(ctx context.Context) (*App, error)

Build validates the provider graph, freezes registrations and resolves every service constructor before returning. It never boots a provider or kernel.

func (*Builder) Inspect

func (b *Builder) Inspect(ctx context.Context) (Inspection, error)

Inspect validates the graph and runs pure registration callbacks on a fresh registry. It never invokes service constructors, Boot, Shutdown or kernels, and does not consume the builder. Register callbacks must be repeatable.

func (*Builder) OverrideContributions

func (b *Builder) OverrideContributions(owner ProviderID, register func(*Registrar) error) *Builder

OverrideContributions explicitly replaces existing typed contributions after every ordinary registration, retaining each contribution's original position. All registrations in this callback must replace an existing contribution of exactly the same type. Missing targets and repeated replacements are errors. The owner is an application scope, never a plugin scope.

func (*Builder) Register

func (b *Builder) Register(providers ...Provider) *Builder

Register adds providers in deterministic declaration order. Dependency order takes precedence. Duplicate IDs fail unless Replace is explicitly requested.

func (*Builder) RegisterPlugin

func (b *Builder) RegisterPlugin(plugins ...Plugin) *Builder

RegisterPlugin snapshots declarations and adds plugins to the same dependency and resource lifecycle as application providers. No hidden init or loader runs.

func (*Builder) Replace

func (b *Builder) Replace(provider Provider) *Builder

Replace explicitly replaces an already declared provider, preserving its declaration position. Replacing a missing ID is an error, not an insertion.

type Collection

type Collection[T any] struct {
	// contains filtered or unexported fields
}

Collection groups typed feature contributions within one explicit service scope. A collection does not discover plugins or construct unrelated scopes.

func NewCollection

func NewCollection[T any](name string) Collection[T]

NewCollection creates a typed contribution collection with the supplied name.

func (Collection[T]) Name

func (c Collection[T]) Name() string

Name returns the collection name.

type ContributionInfo

type ContributionInfo struct {
	Name     string     `json:"name"`
	Type     string     `json:"type"`
	Schema   string     `json:"schema,omitempty"`
	Owner    ProviderID `json:"owner"`
	Replaces ProviderID `json:"replaces,omitempty"`
}

ContributionInfo describes declaration ownership without constructing or formatting the service value. Replaces retains the previous owner on override.

type Dependent

type Dependent interface {
	// Dependencies returns the provider identifiers required by this provider.
	Dependencies() []ProviderID
}

Dependent declares providers that must register and boot before this one.

type Inspection

type Inspection struct {
	Providers     []ProviderInfo            `json:"providers"`
	Plugins       []pluginmanifest.Manifest `json:"plugins"`
	Contributions []ContributionInfo        `json:"contributions"`
}

Inspection is an owned declaration snapshot. It contains no service values, configuration values, callback references or infrastructure connections.

type Kernel

type Kernel interface {
	// Run runs the kernel with the supplied context.
	Run(context.Context) error
}

Kernel owns its accept/work loop and must cooperate with cancellation. Shared infrastructure remains alive until the loop and managed tasks have finished.

type KernelFactory

type KernelFactory func(*Runtime) (Kernel, error)

KernelFactory constructs a kernel from resolved services after providers boot.

type KernelFunc

type KernelFunc func(context.Context) error

KernelFunc adapts a function to a kernel.

func (KernelFunc) Run

func (f KernelFunc) Run(ctx context.Context) error

Run calls the kernel function.

type KernelKind

type KernelKind string

KernelKind selects one of the framework's five runtime kernels.

const (
	HTTP      KernelKind = "http"
	CLI       KernelKind = "cli"
	Worker    KernelKind = "worker"
	Scheduler KernelKind = "scheduler"
	WebSocket KernelKind = "websocket"
)

type Key

type Key[T any] struct {
	// contains filtered or unexported fields
}

Key identifies one typed bootstrap service. Declare a key once and pass the resulting concrete dependency to domain constructors instead of resolving it inside request/business operations.

func NewKey

func NewKey[T any](name string) Key[T]

NewKey declares a service key. Its name is checked at registration/resolution.

func (Key[T]) Name

func (k Key[T]) Name() string

Name returns the service key name.

type Module

type Module struct {
	Name       ProviderID
	Requires   []ProviderID
	OnRegister func(*Registrar) error
	OnBoot     func(context.Context, *Runtime) error
}

Module is a small function-based provider for application composition.

func (Module) Boot

func (m Module) Boot(ctx context.Context, r *Runtime) error

Boot calls OnBoot when supplied; otherwise it succeeds.

func (Module) Dependencies

func (m Module) Dependencies() []ProviderID

Dependencies returns a copy of the required provider identifiers.

func (Module) ID

func (m Module) ID() ProviderID

ID returns the module's provider name.

func (Module) Register

func (m Module) Register(r *Registrar) error

Register calls OnRegister when supplied; otherwise it succeeds.

type Option

type Option func(*settings) error

Option configures an application builder.

func WithClock

func WithClock(source clock.Clock) Option

WithClock injects application time without changing lifecycle deadlines.

func WithLogger

func WithLogger(logger *slog.Logger) Option

WithLogger injects an application logger without changing slog.Default.

func WithMaintenance

func WithMaintenance(gate *maintenance.Gate) Option

WithMaintenance supplies the application's admission gate, for example one shared with a fleet-wide maintenance store. Without it the application uses its recorder's gate, or a fresh gate when observability is not configured. A recorder configured with a different gate is rejected at Build.

func WithObservability

func WithObservability(recorder *observability.Recorder) Option

WithObservability gives this application ownership of one fresh recorder. Build remains pure; Start runs reporters and Shutdown drains them after all other resources. Do not reuse a recorder across apps or run/close it manually after handing it to the builder. Its maintenance gate is shared by kernels.

func WithShutdownTimeout

func WithShutdownTimeout(timeout time.Duration) Option

WithShutdownTimeout sets the whole shutdown budget. It starts when shutdown begins and covers the stop delay, kernel drain and all cleanups, which share its remaining deadline. Run waits for this budget; manual Shutdown calls also respect the deadline on the caller's context. Configure kernel drain periods (for example the HTTP shutdown grace) below it.

func WithStartupTimeout

func WithStartupTimeout(timeout time.Duration) Option

WithStartupTimeout bounds provider boot. Expiry cancels the application lifetime and Start reports fault.Timeout; boot callbacks remain owned until they return. Zero, the default, leaves startup bounded only by its context.

func WithStopDelay

func WithStopDelay(delay time.Duration) Option

WithStopDelay configures a lame-duck period for requested shutdown of a running application. State reports Stopping (so readiness fails) while kernels keep serving; afterwards admission closes and kernels drain. Kernel completion or failure stops immediately. The delay is part of the shutdown budget and must be shorter than it. Zero, the default, disables the delay.

type Plugin

type Plugin interface {
	// Manifest returns the plugin manifest.
	Manifest() pluginmanifest.Manifest
	// Register registers plugin declarations with its registrar.
	Register(*Registrar) error
	// Boot boots the plugin with its runtime and context.
	Boot(context.Context, *Runtime) error
	// Shutdown shuts down the plugin using its runtime and context.
	Shutdown(context.Context, *Runtime) error
}

Plugin is an explicitly linked extension. Register and Manifest are pure declarations. Boot acquires resources; register each successful acquisition immediately with Runtime.OnShutdown, including resources acquired before a later boot failure. Shutdown is called once only after successful Boot.

type Provider

type Provider interface {
	// ID returns the provider's identifier.
	ID() ProviderID
	// Register registers the provider's declarations with its registrar.
	Register(*Registrar) error
}

Provider registers constructors and kernel factories. Register must not open resources or start goroutines; resource acquisition belongs in Boot.

type ProviderID

type ProviderID string

ProviderID identifies an application module or plugin contribution.

func PluginProvider

func PluginProvider(id pluginmanifest.ID) ProviderID

PluginProvider identifies a plugin's scope in the ordinary provider graph. Applications can depend on this ID without a redundant provider wrapper.

type ProviderInfo

type ProviderInfo struct {
	ID           ProviderID   `json:"id"`
	Dependencies []ProviderID `json:"dependencies,omitempty"`
}

ProviderInfo describes a provider and its dependencies.

type Registrar

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

Registrar accepts typed services and kernels during a provider's registration callback. Registrars retained after Build cannot mutate the frozen registry.

func (*Registrar) Kernel

func (r *Registrar) Kernel(kind KernelKind, factory KernelFactory) error

Kernel registers one factory for a runtime kind. Duplicate kinds are errors.

func (*Registrar) Owner

func (r *Registrar) Owner() ProviderID

Owner returns the registrar's owning provider identifier.

func (*Registrar) Plugin

func (r *Registrar) Plugin() (pluginmanifest.Manifest, bool)

Plugin returns the captured manifest when called in a plugin's registration.

type Resolver

type Resolver interface {
	// contains filtered or unexported methods
}

Resolver is a sealed, typed-bootstrap resolution capability. There is no public string-key lookup or exported map of application services.

type ResourceID

type ResourceID string

ResourceID identifies an owned cleanup within its provider scope.

type Runtime

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

Runtime is a provider-scoped view of the running application. Its context is the application lifetime; request-specific contexts remain explicit arguments.

func (*Runtime) Clock

func (r *Runtime) Clock() clock.Clock

Clock returns the runtime's application clock.

func (*Runtime) Context

func (r *Runtime) Context() context.Context

Context returns the runtime context.

func (*Runtime) Go

func (r *Runtime) Go(name TaskID, run func(context.Context) error) error

Go starts a tracked critical task. Any non-cancellation error initiates application shutdown. Use jobs for durable work, not unmanaged goroutines.

func (*Runtime) Logger

func (r *Runtime) Logger() *slog.Logger

Logger returns a logger annotated with the owning provider.

func (*Runtime) Maintenance

func (r *Runtime) Maintenance() *maintenance.Gate

Maintenance returns the application's admission gate, also carried by Context.

func (*Runtime) Observability

func (r *Runtime) Observability() *observability.Recorder

Observability returns the runtime's observability recorder.

func (*Runtime) OnShutdown

func (r *Runtime) OnShutdown(name ResourceID, close func(context.Context) error) error

OnShutdown records an acquired resource immediately, including during partial startup. Cleanups run once in reverse acquisition order, after all managed work exits. Callers retain ownership if registration returns an error.

func (*Runtime) Owner

func (r *Runtime) Owner() ProviderID

Owner returns the owning provider identifier.

func (*Runtime) SelectedKernels

func (r *Runtime) SelectedKernels() []KernelKind

SelectedKernels reports the kernels this process runs. Run and RunKernels select them before providers boot, so OnBoot hooks can start optional background work only beside particular kernels. It is empty when the application was started without selecting a kernel.

func (*Runtime) Services

func (r *Runtime) Services() *Services

Services returns the runtime's service registry.

func (*Runtime) State

func (r *Runtime) State() State

State reports the owning application's synchronized lifecycle state. It does not infer readiness from individual dependency availability.

type Services

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

Services contains fully constructed, immutable bindings. Bound service objects manage their own concurrency; changing a binding is not supported.

type State

type State string

State reports actual lifecycle state. A timed-out Shutdown wait leaves an application Stopping until its outstanding work and cleanup really finish.

const (
	Prepared State = "prepared"
	Starting State = "starting"
	Running  State = "running"
	Stopping State = "stopping"
	Stopped  State = "stopped"
)

type TaskID

type TaskID string

TaskID identifies an owned background operation within its provider scope.

Jump to

Keyboard shortcuts

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