Async-Redis
view release on metacpan or search on metacpan
examples/slow-redis/app.pl view on Meta::CPAN
# Slow request handler - delays 1 second, then returns Redis TIME
async sub _handle_slow_request {
my ($scope, $receive, $send) = @_;
my $start = time();
my $worker = $$;
my ($seconds, $microseconds, $error);
eval {
# Get Redis connection
my $r = await get_redis();
# Non-blocking sleep for 1 second
# This is the key: the event loop can handle other requests during this sleep
await Future::IO->sleep(1);
# Get Redis server time (returns hashref with seconds/microseconds)
my $time = await $r->time;
$seconds = $time->{seconds};
$microseconds = $time->{microseconds};
};
$error = $@;
my $elapsed = sprintf("%.3f", time() - $start);
# Handle errors gracefully
if ($error) {
warn "[slow-redis] Worker $worker error: $error\n";
await $send->({
type => 'http.response.start',
status => 500,
headers => [['content-type', 'text/plain']],
});
await $send->({
type => 'http.response.body',
body => "Redis error: $error\n",
});
return;
}
# Build response
my $body = <<"EOF";
Slow Redis Response
===================
Worker PID: $worker
Redis Time: $seconds.$microseconds
Request took: ${elapsed}s (including 1s sleep)
This request intentionally waits 1 second to demonstrate non-blocking I/O.
Run multiple concurrent requests - they should all complete in ~1 second total!
Test with:
for i in 1 2 3 4 5; do curl -s http://localhost:5001/ & done; wait
EOF
await $send->({
type => 'http.response.start',
status => 200,
headers => [
['content-type', 'text/plain; charset=utf-8'],
['x-worker-pid', "$worker"],
['x-elapsed', $elapsed],
],
});
await $send->({
type => 'http.response.body',
body => $body,
});
}
# Fast request handler - no delay, for comparison
async sub _handle_fast_request {
my ($scope, $receive, $send) = @_;
my $start = time();
my $worker = $$;
my ($seconds, $microseconds, $error);
eval {
my $r = await get_redis();
my $time = await $r->time;
$seconds = $time->{seconds};
$microseconds = $time->{microseconds};
};
$error = $@;
my $elapsed = sprintf("%.6f", time() - $start);
if ($error) {
warn "[slow-redis] Worker $worker error: $error\n";
await $send->({
type => 'http.response.start',
status => 500,
headers => [['content-type', 'text/plain']],
});
await $send->({
type => 'http.response.body',
body => "Redis error: $error\n",
});
return;
}
my $body = "Fast: worker=$worker redis_time=$seconds.$microseconds elapsed=${elapsed}s\n";
await $send->({
type => 'http.response.start',
status => 200,
headers => [['content-type', 'text/plain']],
});
await $send->({
type => 'http.response.body',
body => $body,
});
}
# Lifespan handler
async sub _handle_lifespan {
my ($scope, $receive, $send) = @_;
( run in 2.651 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )