kernel

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package kernel boots the application.

It is the equivalent of Laravel's bootstrap/app.php: the single place where an application is composed. One difference matters: the Kernel boots ONCE, at process start, not per request, so nothing here may assume request scope.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatRoutes

func FormatRoutes(routes []httpx.Route) string

FormatRoutes renders the route table for the terminal, grouped by module and sorted by pattern. It is here, and not in the CLI, so that every project prints the same table.

Types

type Bootable

type Bootable interface {
	Boot(ctx context.Context) error
}

Bootable is optional: implement it when the module needs to prepare state at boot -- open a pool, warm a cache, register codecs.

type Closable

type Closable interface {
	Close(ctx context.Context) error
}

Closable is optional: implement it to release resources on shutdown.

type Diagnostic added in v0.6.0

type Diagnostic interface {
	Diagnose(ctx context.Context) []string
}

Diagnostic is optional: the module reports what it knows about the state of the system, in sentences a person can act on.

It feeds the error page. The most useful hint is often about something that happened outside the failing request -- the outbox stuck for four minutes, a job that has not run -- and a page that only looks at the request cannot see any of it.

Return nothing when there is nothing wrong. A diagnosis that always says something is a diagnosis nobody reads.

type Health

type Health interface {
	Health(ctx context.Context) error
}

Health is optional and feeds `aru doctor` and the /_arandu/health endpoint.

type Kernel

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

Kernel holds the composed application: configuration, modules, the global middleware pipeline and the router.

func New

func New(cfg config.Config) *Kernel

New assembles the kernel. It opens no connection and listens on no port -- that is Boot and Run.

func (*Kernel) Boot

func (k *Kernel) Boot(ctx context.Context) error

Boot initializes modules and registers routes. It fails fast: if any module fails to boot the process does not come up. There is no silent degraded mode.

func (*Kernel) Config

func (k *Kernel) Config() config.Config

Config returns the configuration the kernel was built with.

func (*Kernel) Diagnose added in v0.6.0

func (k *Kernel) Diagnose(ctx context.Context) []string

Diagnose asks every module that implements Diagnostic what is wrong right now, and returns what they say.

Pass it to errorpage.Options.Diagnose. It is not wired automatically because the pipeline is assembled in the open, in the application.

func (*Kernel) Handler

func (k *Kernel) Handler() http.Handler

Handler returns the composed handler: the router wrapped in the global pipeline, with the application logger installed above everything else. Useful for tests, which drive the whole stack without a socket.

The logger has to be outermost. Without it, every Log(ctx) call in a request would fall back to slog.Default() and ignore the configured handler and level, which in production means request logs in the wrong format.

func (*Kernel) Logger

func (k *Kernel) Logger() *slog.Logger

Logger returns the root logger. Request handlers must use observability.Log(ctx) instead, which carries the request id.

func (*Kernel) Migrations

func (k *Kernel) Migrations() []Migration

Migrations collects the migrations of every module, in registration order. Hand the result to data.Migrate.

func (*Kernel) Recorder added in v0.4.0

func (k *Kernel) Recorder() *observability.Recorder

Recorder returns the request buffer behind /_arandu/debug, or nil outside development.

Pass it to middleware.Observe. It is not wired automatically because the pipeline is assembled in the application, in the open, and a middleware that reached back into the kernel for state would be the kind of hidden coupling the explicit wiring exists to avoid.

func (*Kernel) Register

func (k *Kernel) Register(mods ...Module) *Kernel

Register adds modules in the order they will be booted. Order matters: a module may depend on another one already being up.

func (*Kernel) Routes

func (k *Kernel) Routes() []httpx.Route

Routes returns the registered routes. It is empty before Boot, because a module only registers its routes when it boots.

func (*Kernel) Run

func (k *Kernel) Run(ctx context.Context) error

Run starts the server and blocks until SIGINT or SIGTERM, then shuts down gracefully.

func (*Kernel) Shutdown

func (k *Kernel) Shutdown() error

Shutdown stops the server and closes the modules in reverse registration order, which is the only order that respects dependencies between them.

func (*Kernel) Use

func (k *Kernel) Use(mw ...httpx.Middleware) *Kernel

Use adds global middleware to the pipeline. The pipeline order is the order of execution on the way in, and its reverse on the way out.

type Migratable

type Migratable interface {
	Migrations() []Migration
}

Migratable is optional: the module declares its migrations, and the Kernel collects them from every registered module in registration order.

type Migration

type Migration = data.Migration

Migration is a versioned, immutable-once-published schema change.

It is an alias, not a copy: the migration runner lives in the data package, and a module must be able to hand its migrations straight to it.

type Module

type Module interface {
	// Name is the stable identifier of the module: a lowercase slug, no spaces.
	Name() string

	// Routes registers the module's HTTP routes.
	Routes(r *httpx.Router)
}

Module is the only unit of composition in the framework.

A module is a directory. It registers its own routes, its own migrations and its own dependency graph. There is no injection container and no reflection based resolution: the wiring is explicit, and the CLI generates the file that instantiates everything.

Every third-party module implements this interface and nothing else. It is the public contract of the framework -- change it and the whole ecosystem breaks, so change it with great care.

Jump to

Keyboard shortcuts

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