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.