ONE :: Timer不调用子例程

时间:2013-04-16 14:18:49

标签: perl

我在工作中开发的项目有问题。它是一个多线程应用程序。我使用Moose进行面向对象编程,使用ONE :: Timer作为计时器。我认为我没有使用它,因为我的子程序从未被调用过。基本上,这是我的代码:

sub add {
    my ($self, $bot) = @_;
    my $provision_object = $bot->provision->new;
    $provision_object->compute;
}

我的计算方法如下所示:

sub compute {
    <A couple of line code...>
    ONE::Timer->at($time1, sub { <computations1> });
    ONE::Timer->at($time2, sub { <computations2> });
}

time1time2包含时间戳。由于我的脚本是服务器(因此它永远不会完成),我确信在脚本结束之前已达到这些时间。 永远不会调用在time1time2秒之后调用的两个子例程。在ONE::Timer->at方法的documentation中,它说:

  

如果你存储了返回值,它就像一个守卫 - 如果它被破坏了,那么计时器就会被取消。

这就是为什么我不存储我对该方法的调用的返回值。我在这里错过了什么吗?

非常感谢任何答案;)

1 个答案:

答案 0 :(得分:2)

所以,ONE是一个事件循环*,所以你必须在某个时刻进入循环。通常,您可以通过调用ONE->loop()来输入事件循环。

ONE->loop()的调用不会返回,直到您的某个事件侦听器调用ONE->stop()

一种选择是将代码包装在collect块中,例如:

use ONE qw( Collect );
collect {
    # The main body of your program
};

收集只会在您的所有事件都被触发一次后才会返回。

如果你想要绿色线程,也就是说,如果你希望你的事件监听器能够在没有进一步干预的情况下有效地异步运行,那么就编写你的程序:

use EV; # Optional, but everything is better with it
use Coro;
use ONE;

async {
    # Put the body of your program here
    # In order for Coro to trigger and execute your 
    # event handlers, you'd need to be blocking on 
    # IO somewhere in here.

    ONE->stop(); # Call when you want your program to exit
};

ONE->loop();

然而,Coro有自己的警告,你应该在跳入之前阅读它。

使用Github上的版本,这将是等效的

use EV;
use Coro;
use ONE;

ONE->loop(sub {
    # Your main body
    ONE->stop;
});

* ONE是AnyEvent的包装器,它本身不实现事件循环,而是提供了一个平台,用于在AnyEvent周围添加一个非常简洁的抽象。