Asynchronous HTTP Requests Using Mojolicious

This is in response to this article, Asynchronous HTTP Requests in Perl Using AnyEvent - linked to from Perl Weekly. Particularly, this quote:

BTW, if you’re a Perl programmer and you’ve been jealous of all the cool kids and node.js, AnyEvent is how you do node.js-style programming in Perl.

UPDATE: this is a better example.
Doug Wilson gist of HTTP async with Mojo::IOLoop. On my test system, this now runs slightly faster than the AnyEvent::HTTP solutions.

Below is *a* solution using Mojolicous. I am sure there are other frameworks that can do the same thing. Benchmarks showed that the AnyEvent program is faster anywhere from fractions of a ms to one entire second depending on the iteration. In this simple case, AnyEvent::HTTP may be the correct solution, however I think as part of a larger project you are still better off going with an async web framework like Mojolicious.

I tried to keep the same style as the original author for comparison and testing. Almost entirely copied and pasted from the Mojolicious documentation and the original article; here is what I whipped up:

#!/usr/bin/env perl

use strict;
use warnings;

use Mojo::UserAgent;
use Mojo::IOLoop;
use Time::HiRes qw(time);

my $url = [

my $ua = Mojo::UserAgent->new;

my $start = time;

foreach my $u (@$url) {
print "\n";
my $now = time;

$ua->get($u, => sub {
my ($ua, $tx) = @_;
if (my $res = $tx->success) {
print "$u has length " . (length $tx->res->body) . " and loaded in " . (time() - $now) . "ms";
else {
my ($message, $code) = $tx->error;
print "Error for $u : ($code) $message"


print "\nTotal elapsed time: " . (time - $start) . "ms\n";


Great solution, thanks for sharing - I'm having trouble with this when trying to check >100 URLs though - in that anything past 70-80 URLs is just thrown away with a connection error.

Any idea why?

But where is async here?

Leave a comment

About Jesse Shy

user-pic Perl pays for my travel addiction.