Mojo :: UserAgent неблокирующая производительность против блокировки - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть следующий код:

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

my @ids = qw(id1 id2 id3);

foreach (@ids) {    
    my $input = $_;
    my $res = $ua->get('http://my_site/rest/id/'.$input.'.json' => sub {
        my ($ua, $res) = @_;
        print "$input =>" . $res->result->json('/net/id/desc'), "\n";
    });    
}

Mojo::IOLoop->start unless Mojo::IOLoop->is_running;

Почему, когда я запускаю приведенный выше код (без блокировки), это занимает около 6 секунд, а при запуске кода как блокирующего, то есть внутри цикла что-то вроде:

 my $res = $ua->get('http://my_site/rest/id/'.$input.'.json');
 print "$input =>" . $res->result->json('/net/id/desc'), "\n";

без последней строки это займет около 1 секунды?

Почему блокирующий код быстрее, чем неблокирующий код?

1 Ответ

0 голосов
/ 10 сентября 2018

Первое, что нужно проверить, когда все произошло. Я не мог получить такую ​​же задержку. Не забудьте попробовать каждый раз несколько раз, чтобы определить выбросы, где есть сбой сети. Обратите внимание, что вторым аргументом неблокирующей подпрограммы является объект транзакции, обычно записываемый как $tx, где объект ответа обычно записывается res:

use Mojo::Util qw(steady_time);

say "Begin: " . steady_time();
END { say "End: " . steady_time() }

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

my @ids = qw(id1 id2 id3);

foreach (@ids) {
    my $input = $_;
    my $res = $ua->get(
        $url =>
        sub {
            my ($ua, $tx) = @_;
            print "Fetched\n";
            }
        );
    }

Одна из возможностей заключается в том, что keep-alive удерживает открытое соединение. Что произойдет, если вы выключите это?

    my $res = $ua->get(
        $url =>
        { Connection => 'close' }
        sub {
            my ($ua, $tx) = @_;
            print "Fetched\n";
            }
        );

Вот версия, которая использует обещания , к которой вы захотите привыкнуть, когда к ней придет больше вещей из Mojo:

use feature qw(signatures);
no warnings qw(experimental::signatures);

use Mojo::Promise;
use Mojo::Util qw(steady_time);
use Mojo::UserAgent;
my $ua = Mojo::UserAgent->new;

say "Begin: " . steady_time();
END { say "End: " . steady_time() }

my @ids = qw(id1 id2 id3);

my @gets = map {
    $ua->get_p( 'http://www.perl.com' )->then(
        sub ( $tx ) { say "Fetched: " . steady_time() },
        sub { print "Error: @_" }
        );
    } @ids;

Mojo::Promise->all( @gets )->wait;
...