以下脚本应该演示我在使用mod_perl在OpenBSD5.2上使用Mojolicious时遇到的问题。
脚本工作正常4次,在mod_perl下被称为CGI。脚本的其他运行导致Mojolicious不返回异步帖子。通常在数据到达时调用的子类似乎不再被调用。从命令行运行脚本工作正常,因为perl然后从头开始完全重新初始化,而mod_perl则不是这样。停止并启动Apache重新初始化mod_perl,以便脚本可以再运行4次。
我只使用OpenBSDs端口树(2.76)中提供的版本中的Mojolicious在OpenBSD5.2上测试了这个。我觉得这有点老了,但这就是OpenBSD带来的。
我在这里做错了吗?或者Mojolicious可能有一些循环引用或导致此问题的东西?
我对正在使用的平台(OpenBSD)没有任何影响。所以请不要建议“使用Linux并安装最新的Mojolicious版本”。但是,如果您确定运行更高版本的Mojolicous将解决问题,我可能会获得安装它的权限(虽然我还不知道如何做到这一点)。
提前致谢!
吨。
这是脚本:
#!/usr/bin/perl
use diagnostics;
use warnings;
use strict;
use feature qw(switch);
use CGI qw/:param/;
use CGI qw/:url/;
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
use Mojo::IOLoop;
use Mojo::JSON;
use Mojo::UserAgent;
my ($activeconnections, $md5, $cgi);
my $ua = Mojo::UserAgent->new;
$ua->max_redirects(0)->connect_timeout(3)->request_timeout(6); # Timeout 6 seconds of which 3 may be connecting
my $delay = Mojo::IOLoop->delay();
sub online{
my $url = "http://www.backgroundtask.eu/Systeemtaken/Search.php";
$delay->begin;
$activeconnections++;
my $response_bt = $ua->post_form($url, { 'ex' => $md5 }, sub {
my ($ua, $tx) = @_;
my $content=$tx->res->body;
$content =~ m/(http:\/\/www\.backgroundtask\.eu\/Systeemtaken\/taakinfo\/.*$md5\/)/;
if ($1){
print "getting $1\n";
my $response_bt2 = $ua->get($1, sub {
$delay->end();
$activeconnections--;
print "got result, ActiveConnections: $activeconnections\n";
($ua, $tx) = @_;
my $filename = $tx->res->dom->find('table.view')->[0]->find('tr.even')->[2]->td->[1]->all_text;
print "fn = " . $filename . "\n";
}
)
} else {
print "query did not return a result\n";
$activeconnections--;
$delay->end;
}
});
}
$cgi = new CGI;
print $cgi->header(-cache_control=>"no-cache, no-store, must-revalidate") . "\n";
$md5 = lc($cgi->param("md5") || ""); # read param
$md5 =~ s/[^a-f0-9]*//g if (length($md5) == 32); # custom input filter for md5 values only
if (length $md5 != 32) {
$md5=lc($ARGV[0]);
$md5=~ s/[^a-f0-9]*//g;
die "invalid MD5 $md5\n" if (length $md5 ne 32);
}
online;
if ($activeconnections) {
print "waiting..., activeconnections: $activeconnections\n" for $delay->wait;
}
print "all pending requests completed, activeconnections is " . $activeconnections . "\n";
print "script done.\n md5 was $md5\n";
exit 0;
答案 0 :(得分:0)
嗯,我不想这么说,但这里有很多错误。最明显的是你对... for $delay->wait
的使用没有多大意义。您还要将数字与ne
而不是!=
进行比较。不my
- 更深层回调中的参数似乎对异步样式代码有问题。
然后会出现一些代码异味,比如网址的regexing和不必要地关闭$md5
变量。
最后,当Mojolicious可以在CGI下运行时,为什么要使用CGI.pm呢?当你这样做时,IOLoop已经在运行,所以有些事情会变得更容易。是的,我明白你使用的是Mojolicious提供的系统,不过我觉得我应该提一下当前的版本是3.93: - )
无论如何,这是一个例子,它删除了很多东西,但仍然应该与示例完全相同。当然,如果网站没有有效的md5,我就无法测试它(如果没有样本数据,我也无法摆脱url正则表达式。)
#!/usr/bin/perl
use Mojolicious::Lite;
use Mojo::UserAgent;
my $ua = Mojo::UserAgent->new;
$ua->max_redirects(0)->connect_timeout(3)->request_timeout(6); # Timeout 6 seconds of which 3 may be connecting
any '/' => sub {
my $self = shift;
$self->res->headers->cache_control("no-cache, no-store, must-revalidate");
my $md5 = lc($self->param("md5") || ""); # read param
$md5 =~ s/[^a-f0-9]*//g if (length($md5) == 32); # custom input filter for md5 values only
if (length $md5 != 32) {
$md5=lc($ARGV[0]);
$md5=~ s/[^a-f0-9]*//g;
die "invalid MD5 $md5\n" if (length $md5 != 32);
}
$self->render_later; # wait for ua
my $url = "http://www.backgroundtask.eu/Systeemtaken/Search.php";
$ua->post_form($url, { 'ex' => $md5 }, sub {
my ($ua, $tx) = @_;
my $content=$tx->res->body;
$content =~ m{(http://www\.backgroundtask\.eu/Systeemtaken/taakinfo/.*$md5/)};
return $self->render( text => 'Failed' ) unless $1;
$ua->get($1, sub {
my ($ua, $tx) = @_;
my $filename = $tx->res->dom->find('table.view')->[0]->find('tr.even')->[2]->td->[1]->all_text;
$self->render( text => "md5 was $md5, filename was $filename" );
});
});
};
app->start;