NAME
PAGI::Lifespan - Wrap a PAGI app with lifecycle management
SYNOPSIS
use PAGI::Lifespan;
use PAGI::App::Router;
my $router = PAGI::App::Router->new;
$router->get('/' => sub { ... });
# Wrap app with lifecycle management
my $app = PAGI::Lifespan->wrap(
$router->to_app,
startup => async sub {
my ($state) = @_; # State hash injected into every request
$state->{db} = DBI->connect(...);
$state->{config} = { app_name => 'MyApp' };
},
shutdown => async sub {
my ($state) = @_;
$state->{db}->disconnect;
},
);
DESCRIPTION
PAGI::Lifespan wraps any PAGI application with lifecycle management. It handles lifespan.startup and lifespan.shutdown events and injects application state into the scope for all requests.
State Flow
The startup and shutdown callbacks receive a $state hashref as their first argument. Populate this with database connections, caches, configuration, etc. This is similar to how Starlette's lifespan context manager yields state to request.state.
startup => async sub {
my ($state) = @_;
$state->{db} = await connect_to_database();
$state->{cache} = Cache::Redis->new(...);
},
shutdown => async sub {
my ($state) = @_;
$state->{db}->disconnect;
},
For every request, this state is injected into the scope as $scope->{'pagi.state'}. This makes it accessible via:
$req->state->{db} # In HTTP handlers
$ws->state->{db} # In WebSocket handlers
$sse->state->{db} # In SSE handlers
METHODS
new
my $lifespan = PAGI::Lifespan->new(
app => $pagi_app, # Required
startup => async sub { my ($state) = @_; }, # Optional
shutdown => async sub { my ($state) = @_; }, # Optional
);
Both startup and shutdown callbacks receive the shared state hashref as their first argument.
wrap
my $app = PAGI::Lifespan->wrap($inner_app, startup => ..., shutdown => ...);
Class method shortcut that creates a wrapper and returns the app coderef.
to_app
my $app = $lifespan->to_app;
Returns the wrapped PAGI application coderef.
state
my $state = $lifespan->state;
Returns the state hashref.