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 ¶
- func FormatRoutes(routes []httpx.Route) string
- type Bootable
- type Closable
- type Diagnostic
- type Health
- type Kernel
- func (k *Kernel) Boot(ctx context.Context) error
- func (k *Kernel) Config() config.Config
- func (k *Kernel) Diagnose(ctx context.Context) []string
- func (k *Kernel) Handler() http.Handler
- func (k *Kernel) Logger() *slog.Logger
- func (k *Kernel) Migrations() []Migration
- func (k *Kernel) Recorder() *observability.Recorder
- func (k *Kernel) Register(mods ...Module) *Kernel
- func (k *Kernel) Routes() []httpx.Route
- func (k *Kernel) Run(ctx context.Context) error
- func (k *Kernel) Shutdown() error
- func (k *Kernel) Use(mw ...httpx.Middleware) *Kernel
- type Migratable
- type Migration
- type Module
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FormatRoutes ¶
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 ¶
Bootable is optional: implement it when the module needs to prepare state at boot -- open a pool, warm a cache, register codecs.
type Diagnostic ¶ added in v0.6.0
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 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 ¶
New assembles the kernel. It opens no connection and listens on no port -- that is Boot and Run.
func (*Kernel) Boot ¶
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) Diagnose ¶ added in v0.6.0
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 ¶
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 ¶
Logger returns the root logger. Request handlers must use observability.Log(ctx) instead, which carries the request id.
func (*Kernel) Migrations ¶
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 ¶
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 ¶
Routes returns the registered routes. It is empty before Boot, because a module only registers its routes when it boots.
func (*Kernel) Run ¶
Run starts the server and blocks until SIGINT or SIGTERM, then shuts down gracefully.
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 ¶
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.