Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 带有AnyEvent的主辅助服务器_Perl_Events_Asynchronous - Fatal编程技术网

Perl 带有AnyEvent的主辅助服务器

Perl 带有AnyEvent的主辅助服务器,perl,events,asynchronous,Perl,Events,Asynchronous,我需要编写一个服务器程序,在服务器监听另一端的JSONRPC调用时,它将打开并保持5个实时Telnet、SSH和到服务器的各种连接 我在打开和维护5个连接以及侦听请求方面没有问题: # workers: open_myconnections( 1..5 ); my $w1 = AnyEvent->timer (interval => $seconds, cb => sub { keep_conn_alive(1) }); my $w2 = AnyEvent->timer

我需要编写一个服务器程序,在服务器监听另一端的JSONRPC调用时,它将打开并保持5个实时Telnet、SSH和到服务器的各种连接

我在打开和维护5个连接以及侦听请求方面没有问题:

# workers:
open_myconnections( 1..5 );
my $w1 = AnyEvent->timer (interval => $seconds, cb => sub { keep_conn_alive(1) });
my $w2 = AnyEvent->timer (interval => $seconds, cb => sub { keep_conn_alive(2) });
...

# now listen for requests
use AnyEvent::JSONRPC::Lite;
# master: 
my $server = jsonrpc_server '127.0.0.1', '4423';
$server->reg_cb(
    queue_up => sub {
        my ($res_cv, @params) = @_;
        my $res = send_params_to_connection_queue( @params ); 
        $res_cv->result($res);
    },
);
但现在我一直在努力找出在5个工作进程中分配队列的最佳方式(即非阻塞方式),这就是我的函数
send_params_to_connection_queue()
所做的


任何模块建议都是值得赞赏的,尽管我试图避免使用,因为这应该是一个非常小的服务器,除非没有其他合理的选择,否则我会通过。

在YAPC::NA 2011,我了解了一个非常好的排队系统,名为ZeroMQ。在和处使用Perl绑定

|-----ssh工作者 JSONRPC侦听器EventLoop-->QueuengSystem-->--telnet worker |-----等等。
在YAPC::NA 2011上,我了解了一个非常好的排队系统ZeroMQ。在和处使用Perl绑定

|-----ssh工作者 JSONRPC侦听器EventLoop-->QueuengSystem-->--telnet worker |-----等等。 只有你知道什么是“最好的”,但如何做到这一点有一个一般的模式,也许这才是你真正的问题

基本上,您需要一个队列,比如一个数组,用于存储所有尚未发送的请求:

我的@queue

然后,每次要执行请求时,首先将数据推送到队列上,然后调用“调度程序”函数:

子do_需求{ 我的($data,$cb)=@; 推送@queue,[$data,$cb]; 调度程序; }

日程安排功能的目的是选择一名工作人员并启动 下一请求:

子调度器{ @排队或返回;#与空队列无关

  for my $worker (@workers) {
     if ("$worker is free") {
        my ($data, $cb) = @{ shift @queue };
        $worker->doit (sub {
           &scheduler;
           $cb->(@_); # call original callback
        });
        return;
     }
  }
}

这样做的目的是找到一个自由工作者,向其发送请求(“doit”),然后 完成后,它会再次调用调度程序

这取决于你如何决定一个工人是否“自由”。比如你 始终可以选择未完成请求数最少的工作进程。 或者,您可以选择一个具有(比如)少于5个未完成请求的工作人员。 或者哪种方式最好

重要的是,无论何时,一个工人可能会获得自由(因为一份工作 完成),再次调用调度程序,以对下一个作业进行排队

这样,您可以在不忘记的情况下对工人施加任意限制 关于您需要执行但由于此限制无法发送的作业

这项技术有很多变量,但基本思想始终是 相同:首先是队列,然后有一个函数,您可以在之后调用这两个函数 排队和作业完成后,哪个应分发排队的 工作

在event speak中,有两个事件可能需要发送 请求:创建/排队新作业/请求时,以及未完成的 工作完成了。

只有你知道什么是“最好的”,但如何做到这一点有一个通用模式,也许这才是你真正的问题

基本上,您需要一个队列,比如一个数组,用于存储所有尚未发送的请求:

我的@queue

然后,每次要执行请求时,首先将数据推送到队列上,然后调用“调度程序”函数:

子do_需求{ 我的($data,$cb)=@; 推送@queue,[$data,$cb]; 调度程序; }

日程安排功能的目的是选择一名工作人员并启动 下一请求:

子调度器{ @排队或返回;#与空队列无关

  for my $worker (@workers) {
     if ("$worker is free") {
        my ($data, $cb) = @{ shift @queue };
        $worker->doit (sub {
           &scheduler;
           $cb->(@_); # call original callback
        });
        return;
     }
  }
}

这样做的目的是找到一个自由工作者,向其发送请求(“doit”),然后 完成后,它会再次调用调度程序

这取决于你如何决定一个工人是否“自由”。比如你 始终可以选择未完成请求数最少的工作进程。 或者,您可以选择一个具有(比如)少于5个未完成请求的工作人员。 或者哪种方式最好

重要的是,无论何时,一个工人可能会获得自由(因为一份工作 完成),再次调用调度程序,以对下一个作业进行排队

这样,您可以在不忘记的情况下对工人施加任意限制 关于您需要执行但由于此限制无法发送的作业

这项技术有很多变量,但基本思想始终是 相同:首先是队列,然后有一个函数,您可以在之后调用这两个函数 排队和作业完成后,哪个应分发排队的 工作

在event speak中,有两个事件可能需要发送 请求:创建/排队新作业/请求时,以及未完成的
工作完成。

我不确定在这种情况下分发的确切含义,您能详细说明吗?我的意思是,将传入的请求分配给5个可用的工作人员之一。我不确定在这种情况下分发的确切含义,您能详细说明吗?我的意思是,将传入请求分配给5个可用工作进程中的一个。还有AnyMQ和AnyEvent::MP(后者仅在您有多个进程/节点时才有意义)AnyEvent::MP非常棒!我可能会用这个。但我的问题是Net::OpenSSH和Telnet阻塞了库,这使得使用事件队列变得非常困难。您使用非阻塞主事件循环,它以非阻塞方式将阻塞服务(Telnet等)要完成的工作排队,主循环还设置了一个回调函数,这样当队列工作器完成阻塞调用时,它可以向运行回调的主循环发回信号,通常对数据进行后处理,并将数据包发送给事件请求者。我在上面的回复中画了一幅图。还有AnyMQ和AnyEvent::MP(后者只在有多个进程/节点时才有意思)AnyEvent::MP很棒!我可能会用它