我正在使用Mojolicious非阻塞方法(Promises)从外部系统请求数据。 1)我希望立即通知用户进程已经开始;2)我想扩展该程序。
下面的代码适用于一小组数字(几百个),但是对于更多数字,我会收到错误信息 [error] Can't create pipe: Too many open files at /path/lib/perl5/Mojo/IOLoop.pm line 156.
问题1)如何限制我生成的Promise数量(我在下面的代码中使用了map
):
#!/usr/bin/env perl
use Mojolicious::Lite;
use Mojolicious::Plugin::TtRenderer;
sub isPrime
{
my ($n) = @_;
my $e = sqrt($n);
for (my $i=2; $i<$e; $i++) {
return 0 if $n%$i==0;
}
return 1;
}
sub makeApromise
{
my ($number) = @_;
my $promise = Mojo::Promise->new;
Mojo::IOLoop->subprocess(
sub { # first callback is executed in subprocess
my %response;
# Simulate a long computational process
$response{'number'} = $number;
$response{'isPrime'} = isPrime($number);
return \%response;
},
sub { # second callback resolves promise with subprocess result
my ($self, $err, @result) = @_;
return $promise->reject($err) if $err;
$promise->resolve(@result);
},
);
return $promise;
}
plugin 'tt_renderer'; # automatically render *.html.tt templates
any '/' => sub {
my ($self) = @_;
my $lines = $self->param( 'textarea' );
if ($lines) {
my @numbers;
foreach my $number (split(/\r?\n/, $lines)) {
push(@numbers, $number) if $number =~ /^\d+$/;
}
if (@numbers) {
####################################
### This is the problem below... ###
my @promises = map { makeApromise($_) } @numbers;
####################################
# MojoPromise Wait
Mojo::Promise->all(@promises)
->then(sub {
my @values = map { $_->[0] } @_;
foreach my $response (@values) {
#print STDERR $response->{'number'}, " => ", $response->{'isPrime'}, "\n";
# Prepare email...
}
# Send an email...
})
#->wait # Don't wait? I want to tell the user to wait for an email as quickly as possible...
if @promises;
}
$self->stash(done => "1",);
}
$self->render(template => 'index', format => 'html', handler => 'tt');
};
app->start;
__DATA__
@@ index.html.tt
<!DOCTYPE html>
<html lang="en">
<head>
<title>Make A Promise</title>
</head>
<body>
[% IF done %]
<h3>Thank you! You will receive an email shortly with the results.</h3>
[% ELSE %]
<h3>Enter numbers...</h3>
<form role="form" action="/" method="post">
<textarea name="textarea" rows="5" autofocus required></textarea>
<button type="submit">Submit</button>
</form>
[% END %]
</body>
</html>
我注释掉了wait
代码;但似乎代码仍在阻塞。 问题2) 当我存储done
变量时,如何立即通知用户进程已经开始?
map
的@numbers
来进行节流(管理它们的提交方式)?此外,你是如何运行所有这些代码的?对我来说它总是崩溃。 - zdim[02:54:26 abhasker@wsl -> temp$ morbo bug.pl
输出:Server available at http://127.0.0.1:3000
。 - AbhiNickzmap
的@numbers
进行节流的示例? - h q