santa100
santa100

Reputation: 255

Capture both resolved and rejected in Perl's Mojo::Promises

I'm playing with Mojo::UserAgent and Mojo::Promise to run non-blocking calls to 3 services A, B, and C. The problem is it works fine when all the services connect/resolve, but if one of those, say, service C is unable to connect, the whole thing fail. Is there a way to capture all services (connect and Not-connect)? Any insight is greatly appreciated. Thanks!

 my @urls = (   
   'https://hostA/serviceA',  # ServcieA connects and returns some text
   'https://hostB/serviceB',  # ServiceB connects and returns some text
   'https://hostC/serviceC',  # ServiceC refuses to connect 
 ); 
 my $ua = Mojo::UserAgent->new; 
 my @promises = map { $ua->get_p($_) } @urls;
 Mojo::Promise->all( @promises )->then(   
   sub {
     for my $tx (map { $_->[0] } @_) {
       print "Service result: $tx->res->text";
     }#end for   
   }#end sub 
 )->catch(   
   sub {
     for my $err (map { $_->[0] } @_) {
       print "ERROR: $err";
     }#end for   
   }#end sub 
 )->wait;

Upvotes: 1

Views: 235

Answers (1)

brian d foy
brian d foy

Reputation: 132918

I think I'd make it simpler. Give each Promise its own handlers, then simply put all of those together. Inside the code refs in then, do whatever you need to do:

#!perl
use v5.10;

use Mojo::Promise;
use Mojo::UserAgent;

my @urls = qw(
    https://www.yahoo.com
    https://hostB/serviceB
    https://hostC/serviceC
    );

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

 my @promises = map {
    my $url = $_;
    $ua->get_p( $url )->then(
        sub { say "$url connected" },
        sub { say "$url failed" },
        );
    } @urls;


 Mojo::Promise->all( @promises )->wait;

This outputs which connected or failed, although I could have also marked their status in some data structure or database:

https://hostB/serviceB failed
https://hostC/serviceC failed
https://www.yahoo.com connected

I have many other Promises examples in Mojo Web Clients.

Upvotes: 3

Related Questions