Async-Redis
view release on metacpan or search on metacpan
examples/slow-redis/app.pl view on Meta::CPAN
headers => [['content-type', 'text/plain']],
});
await $send->({
type => 'http.response.body',
body => $body,
});
}
# Lifespan handler
async sub _handle_lifespan {
my ($scope, $receive, $send) = @_;
while (1) {
my $event = await $receive->();
if ($event->{type} eq 'lifespan.startup') {
print STDERR "[slow-redis] Worker $$ starting...\n";
# Pre-connect to Redis
eval { await get_redis() };
if ($@) {
warn "[slow-redis] Redis connection failed: $@\n";
} else {
print STDERR "[slow-redis] Redis connected\n";
}
await $send->({ type => 'lifespan.startup.complete' });
}
elsif ($event->{type} eq 'lifespan.shutdown') {
print STDERR "[slow-redis] Worker $$ shutting down...\n";
$redis->disconnect if $redis;
await $send->({ type => 'lifespan.shutdown.complete' });
last;
}
}
}
# App coderef returned to PAGI (do 'file' returns last expression)
no warnings 'void';
$app;
__END__
=head1 NAME
slow-redis - Demonstrate non-blocking I/O with intentional delay
=head1 SYNOPSIS
# Start Redis
docker run -d -p 6379:6379 redis
# Run the server
REDIS_HOST=localhost pagi-server --app examples/slow-redis/app.pl --port 5001
# Test single request (takes ~1 second)
curl http://localhost:5001/
# Test 5 concurrent requests (should still take ~1 second total!)
time (for i in 1 2 3 4 5; do curl -s http://localhost:5001/ & done; wait)
# Compare with fast endpoint (no delay)
curl http://localhost:5001/fast
=head1 DESCRIPTION
This example demonstrates non-blocking I/O by intentionally sleeping for
1 second before returning a response. Despite the delay, the server can
handle many concurrent requests because the sleep is non-blocking.
With traditional blocking I/O:
- 5 sequential requests = 5 seconds
- 5 concurrent requests to a single-threaded server = 5 seconds
With non-blocking I/O (this example):
- 5 sequential requests = 5 seconds
- 5 concurrent requests = ~1 second (all sleep concurrently)
=head1 ENDPOINTS
=over 4
=item GET /
Returns Redis TIME after a 1-second non-blocking sleep.
=item GET /fast
Returns Redis TIME immediately (no delay), for comparison.
=back
=cut
( run in 1.217 second using v1.01-cache-2.11-cpan-524268b4103 )