in reply to LWP::UserAgent non-blocking calls

There is/was Coro::LWP, which integrated LWP with Coro, but so far I have not found a good way to make LWP::UserAgent-based scripts parallel without rewriting them.

I am fond of using Future, but also had good success using Mojo::UserAgent. Both have APIs somewhat different from LWP::UserAgent though.

With both systems, the logic would very much like the approach you outlined above:

# Using (my own) Future::HTTP, which provides an AnyEvent::HTTP-like A +PI my $ua = Future::HTTP->new(); # Fire off all requests at once, rate limiting etc. is left as an exer +cise my @outstanding; for my $url (@requests) { my $res = $ua->http_get($url)->then(sub { my( $body, $data ) = @_; # ... handle the response return $body }); push @outstanding, $res; }; while( @outstanding ) { my $body = (shift @outstanding)->get; ... };

With Mojolicious you can look at COWS::Crawler, which also implements something like the following API:

my $crawler = COWS::Crawler->new(); $crawler->submit_request({ method => 'GET', url => $url, info => { u +rl => $url }} ); while( my ($page) = $crawler->next_page ) { my $body = $page->{res}->body; my $url = $page->{req}->req->url; ... };

But all of these approaches need a real rewrite of the formerly sequential program logic into asynchronous execution.

Replies are listed 'Best First'.
Re^2: LWP::UserAgent non-blocking calls
by cavac (Prior) on Oct 22, 2024 at 09:13 UTC

    Maybe i'm doing something wrong or i'm not understanding how Future::HTTP works. But i can't get it to work in the background while the worker does other stuff.

    It always returns false on $ua->is_async(). I can't change my event loop to a different type, and i don't see a way to poll Future::HTTP directly.

    PerlMonks XP is useless? Not anymore: XPD - Do more with your PerlMonks XP
    Also check out my sisters artwork and my weekly webcomics

      I fell into the trap myself. Future::HTTP uses whatever other event loop you already have loaded. If you have no event loop loaded, it uses HTTP::Tiny, which is synchronous.

      The "correct" approach is to load the event loop first (use IO::Async; (or whatever)) and then load/use HTTP::Future.

      I should make this more clear in the documentation resp. fix the usage so that this trap does not exist anymore.