我们正在构建一个具有复杂逻辑的大型应用程序,它由模块组成.我曾经用更简单的方法构建更大规模的方法,例如,
# fig. 1
package Foo;
sub highlevel {
my ($self, $user, $event) = @_;
my $session = $self->get_session($user);
my $result = $self->do_stuff($session, $event);
$self->save_session($session);
return $result;
};
Run Code Online (Sandbox Code Playgroud)
(当然这是简化的).返回结果,抛出异常,每个人都很开心.
现在,我们正在转向AnyEvent.我的模块不是最高级别,所以我做不到
# fig. 2
my $cv = AnyEvent->condvar;
# do stuff
return $cv->recv;
Run Code Online (Sandbox Code Playgroud)
到目前为止我见过的大多数AE模块都是这样的:
# fig. 3
$module->do_stuff( $input,
on_success => sub { ... },
on_error => sub { ... }
);
Run Code Online (Sandbox Code Playgroud)
所以我完成了对低级方法的重写并尝试继续使用highlevel()和...
# fig. 4
package Foo;
sub highlevel {
my ($self, $user, $event, %callbacks) = @_;
my $done = …
Run Code Online (Sandbox Code Playgroud) 我怎么能让计时器"可见"?这个例子返回(始终与睡眠时间相关)2
(我期望类似于睡眠时间).
#!/usr/local/bin/perl
use warnings;
use 5.014;
use AnyEvent;
my $c = 0;
my $cv = AnyEvent->condvar;
my $once_per_second = AnyEvent->timer (
after => 0,
interval => 1,
cb => sub {
$c++;
$cv->send;
},
);
sleep 5;
$cv->recv;
say $c;
Run Code Online (Sandbox Code Playgroud) 我一直在对这个主题进行大量的研究,虽然有一些问题与我有关,但我真的很难理解如何使用AnyEvent和www-mechanize正确地进行异步编程.我正在努力坚持机械化,因为它有一个干净的界面,并且内置了我期望的功能:(比如获取网站的所有图像等).如果没有可靠/好的方法来做我想做的事情,那么我将开始关注AnyEvent :: HTTP,但我想我会先朝那个方向询问.
我是AnyEvent编程的新手,但之前用回调做了大量的perl和javascript/jquery异步调用.这些对我来说很有意义,但它不是用AnyEvent + Mech点击我.
这是我正在处理的代码,它从上游队列中提取URL.给出URL,我想得到一个说明拉入页面上的所有图像,然后异步.抓住所有图像.
所以伪代码看起来像这样:
我读过,我不能(在研究错误之后)在AnyEvent回调中阻塞.如何构建我的程序以进行异步调用而不阻塞?
AE事件只能在AE感知功能阻止时处理,所以我使用的是LWP :: Protocol :: AnyEvent :: http.它用可识别AE的AnyEvent :: HTTP替换LWP(Net:HTTP)的普通HTTP后端.
工作人员创建如下:
my Worker->new(upstream_job_url => "tcp://127.0.0.1:5555', run_on_create => 1);
Run Code Online (Sandbox Code Playgroud)
异步部分是sub _recv_msg,它调用_proc_msg.
我已经有一个AnyEvent循环,根据ZeroMQ perl绑定文档观察ZeroMQ套接字...
任何帮助非常感谢!
码:
package Worker;
use 5.12.0;
use Moose;
use AnyEvent;
use LWP::Protocol::AnyEvent::http;
use ZMQ::LibZMQ3;
use ZMQ::Constants qw/ZMQ_PUSH ZMQ_PULL ZMQ_POLLIN ZMQ_FD/;
use JSON;
use WWW::Mechanize;
use Carp;
use Coro;
has 'max_children' => (
is => 'rw',
isa => 'Int',
required => 1,
default …
Run Code Online (Sandbox Code Playgroud) 在一个Mojolicious应用程序中,我正在尝试在单击链接时将ODT文件转换为HTML.我使用shell命令"soffice"转换文件.转换文件需要一些时间.我向用户发送状态消息以通知他进度.我通过写入Mojo :: Log对象发送这些状态更新消息.然后,我在EventSource路由中订阅此日志对象.
然后我遍历文件并使用AnyEvent :: Util run_cmd来执行外部"soffice"程序.
for my $file (@{ $filelist }) {
my $output_dir = './output_dir';
my $cmd = "soffice --headless --convert-to html --outdir '$output_dir' '$file'";
my $cv = AnyEvent->condvar;
my $w;
$w = run_cmd($cmd,
'>' => sub { my $out = shift;
&WriteToLog({ status => "cmd output '$out'..." });
undef $w;
$cv->send;
},
'2>' => sub { my $err = shift;
&WriteToLog({ status => "ERROR '$err'..." });
undef $w;
$cv->send;
}
);
$cv->recv;
}
Run Code Online (Sandbox Code Playgroud)
几乎从主要的AnyEvent教程中复制和粘贴.如果只有很少的文件要转换(大约2或3),那么一切顺利.通过EventSource连接发送的状态消息显示在客户端浏览器上.然后在转换完所有文件后,将呈现网页.
如果要处理更多文件,则会转换一些文件,然后会出现线程标题中的错误消息.
包含上述代码的路由的路由是: …
我正在编写使用 AnyEvent 计时器的 Perl/Tk 程序。如果计时器处于活动状态,我在关闭窗口时遇到问题。我做了这个窗口关闭处理程序:
$self -> {window} -> protocol( 'WM_DELETE_WINDOW' => sub {
undef $self -> {timer};
$self -> {window} -> destroy;
});
Run Code Online (Sandbox Code Playgroud)
如果关闭窗口时计时器处于活动状态,则计时器停止,窗口关闭,但 MainLoop 不会停止。怎么了?
在尝试理解AnyEvent的过程中,我创建了两个定时器,每次定时器都会被触发屏幕.最初都没有工作.但是按照Joshua Barratt的计时器示例,我发现如果我没有undef
计时器的观察者变量,那么计时器的回调根本不会发射.为什么会这样?我怀疑它与范围在perl和/或AnyEvent中的工作方式有关.
这是我的示例程序:
#!/usr/bin/perl
use AE;
my $cv = AE::cv;
sub func1 {
my $spoke = 0;
my $t1; $t1 = AE::timer 0, 1,
sub {
print "Timer 1 Fired\n";
if($spoke++ > 5) {
print "Timer 1 Done\n";
undef $t1;
}
};
print "Timer 1 started\n";
}
sub func2 {
my $spoke = 0;
my $t2; $t2 = AE::timer 0, 1,
sub {
print "Timer 2 Fired\n";
if($spoke++ > 5) {
print "Timer 2 Done\n";
#undef …
Run Code Online (Sandbox Code Playgroud) 我是Perl 5异步流程的新手,并且发现令人兴奋的是,CPAN提供了类似的支持,我们可以在Node.js中使用AnyEvent,IO :: Async等进行类似的支持.但是,本教程提供了一些复杂内容的示例.我需要的只是使用AnyEvent并行运行外部系统命令.
我是否在下面的示例中正确地执行了异步压缩多个文件?请不要担心运行系统命令zip而不是使用CPAN模块; 这个例子纯粹是为了演示运行异步进程的想法......
#!/bin/env perl
use strict;
use AnyEvent;
use AnyEvent::Util;
my $s1 = time;
my $quit_program = AnyEvent->condvar(
cb => sub {
warn "Done async";
}
);
my $result;
$quit_program->begin( sub { shift->send($result) } );
for my $file (@files) {
$quit_program->begin;
my $cv; $cv = run_cmd [qw(zip), "${file}.zip", $file],
"<" , "/dev/null",
">" , "/dev/null",
"2>", "/dev/null";
$cv->cb (sub {
shift->recv and die "command failed";
# undef $cv;
$quit_program->end;
}); …
Run Code Online (Sandbox Code Playgroud) 我正在编写一个用于将消息发布到消息队列(RabbitMQ)的主程序.该程序是用Perl 5编写的,并使用AnyEvent :: RabbitMQ与RabbitMQ进行通信.
以下最小示例(针对我遇到的问题)将在第二个命令上失败,该命令通过相同的通道发送,并显示错误"Channel closed".
use strictures 2;
use AnyEvent::RabbitMQ;
main();
############################################################################
sub main {
_log( debug => 'main' );
my $condvar = AnyEvent->condvar;
my $ar = AnyEvent::RabbitMQ->new;
$ar->load_xml_spec;
_log( debug => 'Connecting to RabbitMQ...' );
$ar->connect(
host => 'localhost',
port => 5672,
user => 'guest',
pass => 'guest',
vhost => '/',
timeout => 1,
tls => 0,
on_success => sub { _on_connect_success( $condvar, $ar, @_ ) },
on_failure => sub { _error( …
Run Code Online (Sandbox Code Playgroud) 我必须编写一个脚本来并行获取一些URL并做一些工作.在过去,我一直习惯于Parallel::ForkManager
这样的事情,但现在我想学习一些新东西并尝试使用AnyEvent
(和AnyEvent::HTTP
或AnyEvent::Curl::Multi
)进行异步编程......但是我在理解AnyEvent时遇到问题并编写了一个脚本应该:
我已阅读了许多手册和教程,但我仍然很难理解阻塞和非阻塞代码之间的差异.我在http://perlmaven.com/fetching-several-web-pages-in-parallel-using-anyevent找到了类似的脚本,其中Szabo先生解释了基础知识,但我仍然无法理解如何实现以下内容:
...
open my $fh, "<", $file;
while ( my $line = <$fh> )
{
# http request, read response, update MySQL
}
close $fh
...
Run Code Online (Sandbox Code Playgroud)
...并在这种情况下添加并发限制.
我非常感谢你的帮助;)
根据池上的建议,我Net::Curl::Multi
试了一下.我对结果非常满意.经过多年的使用Parallel::ForkManager
只是为了同时抓取成千上万的URL,Net::Curl::Multi
似乎很棒.这是我while
在filehandle 上循环的代码.它似乎应该工作,但考虑到这是我第一次写这样的东西,我想请更多有经验的Perl用户看一看,告诉我是否有一些潜在的错误,我错过了什么等等.另外,如果我可能会问:因为我不完全理解Net::Curl::Multi
并发是如何工作的,请告诉我是否应该在将MySQL UPDATE命令(via DBI
)置于RESPONSE
循环内时出现任何问题(除了更高的服务器负载之外 - 我希望最终脚本能够运行约50名并发N::C::M
工人,可能更多).
#!/usr/bin/perl
use Net::Curl::Easy qw( :constants );
use Net::Curl::Multi qw( ); …
Run Code Online (Sandbox Code Playgroud) 最近我遇到了一个很棒的perl模块"AnyEvent",它允许用户进行异步/事件驱动的编程.
创建了以下代码片段,工作正常.我遇到的问题是,在打开并关闭许多套接字后,它很快耗尽了所有客户端端口("netstat -ant"显示20,000多个套接字处于TIME_WAIT状态).
$hdl = new AnyEvent::Handle (
connect => [$ip, $port],
on_connect=> sub {
my ($handle, $host, $port, $tmp) = @_;
#print "connect routine for $handle->{ue}\r\n";
#update states.
},
on_read => sub {
my $hdl = $_[0];
#read data
#send response.
});
Run Code Online (Sandbox Code Playgroud)
我想知道是否可以使用IO :: Socket :: INET创建TCP套接字,然后在AnyEvent :: Handle中使用新创建的套接字:
my $sock = IO::Socket::INET->new( Proto => 'tcp',
PeerAddr => $ue->{vars}->{ip},
PeerPort => $ue->{vars}->{dstPort},
ReusePort => 1,
KeepAlive => 1
) || die "failed to setup outsock $@\n";
$hdl = new …
Run Code Online (Sandbox Code Playgroud) anyevent ×10
perl ×10
asynchronous ×5
timer ×2
event-driven ×1
io-async ×1
mojolicious ×1
rabbitmq ×1
scope ×1
sockets ×1
tk-toolkit ×1
zeromq ×1