如何在perl plack应用程序中实现非阻塞响应



我正在尝试使用Twiggy::Server(这意味着plack应用程序)编写一个基于perl的web服务器。我想通过运行一些可能耗时的子例程生成数据,然后将其转换为返回到客户端网页的JSON字符串来响应请求(来自网页上的ajax调用)。

你可以在这里看到我的服务器的精简测试版本:http://pastebin.com/iNaDTVwL这个例子显示了我目前的实现所面临的问题;使用AnyEvent::ForkManager来做非阻塞部分的事情会导致'big' json响应的截断。

这个文档将完美地回答我的问题(并更好地解释我正在尝试做什么):https://github.com/jjn1056/Example-PlackStreamingAndNonblocking…如果它完成了。我只是错过了做非阻塞的"正确"方式,而不是使用AnyEvent::ForkManager,这似乎有点黑客。

我个人使用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系统,以便延迟和稍后响应。

所以从评论来看——我对你使用的东西了解不够,不能给你一个具体的回应,但我可以提供一些一般的东西。

使用线程'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队列是处理告诉线程终止的好方法-当然还有其他方法。

相关内容

  • 没有找到相关文章

最新更新