Использование Mojo :: Promise в автономном скрипте Perl - PullRequest
0 голосов
/ 30 декабря 2018

В автономном скрипте Perl мне нужно совершать параллельные вызовы во внешнюю веб-службу (см. Ниже в $number+1).Я думал, что снова буду использовать мой код Mojo :: Promise, но он не сработал - код on_done() не выполняется.

Я открыт для использования лучших подходов в Perl (очереди?).

#!/usr/bin/env perl

use Mojo::IOLoop;
use Mojo::Promise;
use Future::Utils 'fmap_concat';

####### STASH ######
my $result_future; #
####################

my $count = 100;
my @numbers = 1..$count;

if (@numbers) {
    my $result_f = fmap_concat {
        my $number = shift;
        my $p = Mojo::Promise->new;
        Mojo::IOLoop->subprocess(
            sub {
                #sleep 2;
                return $number+1;
            },
            sub {
                my ($subprocess, $err, @result) = @_;
                return $p->reject($err) if $err;
                $p->resolve(@result);
            });
        return $p->with_roles('Mojo::Promise::Role::Futurify')->futurify;
    } foreach => \@numbers, concurrent => 20;

    $result_f
        ->on_done(
        sub {
            my @values = @_;
            foreach my $response (@values) {
                print STDERR "Response='$response'\n";
            }
        })
        ->on_fail(
        sub {
            my $error = shift;
            print STDERR "# ERROR='$error'\n";
        })
        ->on_ready(
        sub {
            $result_future = undef;
        })
        ;

    # Must keep a reference to Futures until we're done with them.
    $result_future = $result_f;
}
print STDERR "Processing $count numbers\n"

1 Ответ

0 голосов
/ 31 декабря 2018

Поскольку вы не используете этот код в уже запущенном цикле событий, вам нужно запустить цикл событий самостоятельно, чтобы что-то произошло.Самый простой способ сделать это - дождаться завершения вашего фьючерса.

$result_f->await;

В этом случае нет необходимости хранить отдельную ссылку $result_future, поскольку этот оператор будет блокироваться до тех пор, пока фьючерс не будет готов.Это и связанный ->get (то есть просто ->await, возвращающий результаты в случае успеха, бросающий исключение в случае неудачи) является основным механизмом, позволяющим Futures последовательно выполнять неблокирующий код.

...