我正在尝试使用Twiggy::Server
(这意味着一个plack应用程序)编写一个基于perl的网络服务器。
我想通过运行一些可能耗时的子程序来响应某些数据的请求(来自网页上的ajax调用),该子程序生成数据然后将其转换为JSON字符串以返回客户端网页。
您可以在此处查看我的服务器的缩减测试版:http://pastebin.com/iNaDTVwL
这个例子显示了我当前实现的问题;使用AnyEvent::ForkManager
执行非阻塞部分会导致截断“大'json响应。
本文档将完美地回答我的问题(并更好地解释我正在尝试做的事情):https://github.com/jjn1056/Example-PlackStreamingAndNonblocking ......如果它已经完成。我只是错过了进行非阻塞的“正确”方式,而不是使用AnyEvent::ForkManager
这似乎有点像黑客。
答案 0 :(得分:1)
我个人使用Net::Async::HTTP::Server::PSGI
。从其概要:
use Net::Async::HTTP::Server::PSGI;
use IO::Async::Loop;
my $loop = IO::Async::Loop->new;
my $httpserver = Net::Async::HTTP::Server::PSGI->new(
app => sub {
my $env = shift;
return [
200,
[ "Content-Type" => "text/plain" ],
[ "Hello, world!" ],
];
},
);
$loop->add( $httpserver );
$httpserver->listen(
addr => { family => "inet6", socktype => "stream", port => 8080 },
on_listen_error => sub { die "Cannot listen - $_[-1]\n" },
);
$loop->run;
显然,这个特别小的示例并未演示任何异步,但您可以完全访问所有IO::Async
系统,以便稍后推迟和响应。
答案 1 :(得分:0)
所以接下来的评论 - 我对你用来给你一个特定回答的东西知之甚少,但可以提供一些通用的东西。
使用线程将'async'作为Perl脚本的一部分:
#!/usr/bin/perl
use strict;
use warnings;
use threads;
use Thread::Queue;
my $input_q = Thread::Queue -> new();
my $success_q = Thread::Queue -> new();
my $failure_q = Thread::Queue -> new();
my $thread_count = 4;
sub spinoff_thread {
while ( my $target = $input_q -> dequeue() )
{
#do something to $target
my @results = `ping -c 10 -i 1 $target`;
if ( $? ) {
$failure_q -> enqueue ( $target );
}
else {
$success_q -> enqueue ( $target );
}
}
}
#main bit
for ( 1..$thread_count ) {
my $thr = threads -> create ( \&spinoff_thread );
}
foreach my $server ( "server1", "server2", "server3", "server4", "server5" ) {
$input_q -> enqueue ( $server );
}
$input_q -> end(); #will cause threads to 'bail out' because that while loop will go 'undef');
#wait for threads to complete.
foreach my $thr ( threads -> list() ) {
$thr -> join();
}
print "Fail:\n", join ("\n", $failure_q -> dequeue() ), "\n";
print "Success:\n"; join ( "\n", $success_q -> dequeue() ), "\n";
关键点在于你的线程 - 基本上是子程序 - 并且可以使用队列来回传递信息。 end
队列是处理告诉线程终止的好方法 - 当然还有其他方法。