NAME
Langertha::Knarr::Stack - The routing parts of a running Knarr, built from one config
VERSION
version 1.103
SYNOPSIS
use Langertha::Knarr::Stack;
my $stack = Langertha::Knarr::Stack->new(
config => $config, # Langertha::Knarr::Config
loop => $loop,
tracing => $tracing, # enabled Langertha::Knarr::Tracing, or undef
request_log => $request_log, # enabled Langertha::Knarr::RequestLog, or undef
);
my $knarr = Langertha::Knarr->new(
handler => $stack->handler,
router => $stack->router,
raw_passthrough => $stack->raw_passthrough,
auth_token => $stack->auth_token,
( $stack->authorizer ? ( authorizer => $stack->authorizer ) : () ),
...
);
# Same loop, tracing and request log, a new config, fresh engines:
my $next = $stack->with_config($new_config);
my $lf = $stack->with_config( $new_config, tracing => $other_tracing );
DESCRIPTION
Everything of a running Knarr that its routing config decides, built the way knarr start builds it: the Langertha::Knarr::Router, the Langertha::Knarr::Handler::Passthrough for the configured upstreams, the Langertha::Knarr::Handler::Router on top of both, wrapped in the Langertha::Knarr::Handler::Tracing and Langertha::Knarr::Handler::RequestLog decorators when "tracing" and "request_log" are given, and the proxy key.
Langertha::Knarr::Admin builds a new stack for every admin push with "with_config" and hands it to the running Knarr in one step. The new stack has its own router, so its engine cache starts empty; the old stack lives on only as long as a request that is still running holds on to it.
config
Required. The Langertha::Knarr::Config the stack is built from.
loop
Optional IO::Async::Loop for the passthrough's HTTP client.
tracing
Optional, enabled Langertha::Knarr::Tracing. Wraps the handler in a Langertha::Knarr::Handler::Tracing. It is a process setting: "with_config" keeps it.
request_log
Optional, enabled Langertha::Knarr::RequestLog. Wraps the handler in a Langertha::Knarr::Handler::RequestLog, outside the tracing. Kept by "with_config" like "tracing".
router
The Langertha::Knarr::Router over "config". Built on first use.
raw_passthrough
The Langertha::Knarr::Handler::Passthrough for "passthrough" in Langertha::Knarr::Config, or undef when no upstream is configured. Built on first use.
handler
The handler chain: Langertha::Knarr::Handler::Router (with "raw_passthrough" as its fallback), inside the tracing and request-log decorators. Built on first use. With "token_auth" in Langertha::Knarr::Config the core is a Langertha::Knarr::Handler::TokenRoutes over "routes" in Langertha::Knarr::Config instead, and there is no "raw_passthrough".
token_store
The Langertha::Knarr::TokenStore behind "authorizer": with "token_auth" in Langertha::Knarr::Config a Langertha::Knarr::TokenStore::Pg over the config's dsn, user, password_env, relation, listen and columns, using "loop"; undef without it. Building the store loads DBD::Pg (a missing one croaks token_auth backend postgresql needs DBD::Pg) but does not connect: the store connects in the process that serves, when Langertha::Knarr starts the "authorizer" there (else on its first lookup), so a forked worker never shares the parent's connection. Can be given to the constructor (tests hand in a Langertha::Knarr::TokenStore::Memory).
authorizer
The Langertha::Knarr::Authorizer::Token over "token_store" with the config's match_model, or undef without token_auth. Langertha::Knarr takes it from the stack (_apply_stack); without one it keeps checking the proxy key. Can be given to the constructor.
auth_token
The proxy key ("proxy_api_key" in Langertha::Knarr::Config), or undef when none is set.
with_config
my $next = $stack->with_config($config);
my $next = $stack->with_config( $config, tracing => $tracing_or_undef );
A new stack for $config with the same "loop", "tracing" and "request_log", and, when $config has the same "token_auth" in Langertha::Knarr::Config section as this stack's config, the same "authorizer" and "token_store" -- a push of other settings must not drop the token check or reconnect to the database. A different (or no) token_auth section gets a fresh store and authorizer. Nothing of this stack's router, engines or passthrough is reused. A tracing argument (an enabled tracing, or undef for none) replaces the tracing: a delivered langfuse section brings its own.
build
$stack->build;
Builds "router", "raw_passthrough", "token_store", "authorizer" and "handler" now, so a config they cannot be built from fails here and not on the first request. Returns the stack.
SUPPORT
Issues
Please report bugs and feature requests on GitHub at https://github.com/Getty/langertha-knarr/issues.
IRC
Join #langertha on irc.perl.org or message Getty directly.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.