【发布时间】:2016-03-22 20:52:25
【问题描述】:
我使用Mojo::IOLoop 来执行应该经常运行的后台任务,并且正在使用Mojo::IOLoop::recurring 执行此操作。我在 Mojo 应用程序本身内执行此操作:
sub startup {
my $self = shift;
$self->setup_routes();
... more setup
my $sleep_time = $self->config()->{sleep_time};
Mojo::IOLoop->recurring($sleep_time => sub {
my $sync = My::BackgroundTask->new(
sleep_time => $sleep_time,
);
$sync->run();
});
local $SIG{TERM} = sub {
Mojo::IOLoop->stop_gracefully;
};
}
当上述循环运行的时间到了,当尝试查看实际应用程序时,站点超时,当它完成时,应用程序再次可用。不知道为什么会这样,有人能解释一下吗?
编辑:
My::BackgroundTask::run
sub run {
my ($self, $data) = @_;
while ( scalar(@{$data}) > 0 ) {
my @batch = splice(@{$data}, 0, 100);
$self->schema->update_batch_of_data( \@batch );
# sleep for a while to not be rude :P
sleep ($self->sleep_time);
}
return 1;
}
【问题讨论】:
-
我想你会发现问题出在
My::BackgroundTask上,你还没有显示出来。是否检查过父任务是否真的被阻塞或根本无法获取资源? -
这不是特别相关,但设置
local $SIG{TERM} = sub { ... }是错误的,因为一旦startup退出,该值将恢复到其原始状态。只是$SIG{TERM} = sub { ... }是正确的 -
@Borodin,嗯,我没有考虑任务中的问题,因为它所做的只是增量查询数据库,在两者之间调用睡眠。调用 sleep() 会是它阻止应用程序的原因吗?
-
我不知道
Mojo::IOLoop在内部是如何工作的,但这是可能的。你是说它会睡$sleep_time秒吗?因为这不是它应该如何工作的。它应该退出并在下次recurring启动它时继续该过程。实际上,每次recurring启动时,您都试图启动该任务的另一个副本,并且您的任务可能因为无法启动多个任务而挂起?只是一个猜测,它会从$sync->run()返回吗?$sync是什么东西? -
是的,您需要一个类似的
recurring计时器,但在每个步骤中只做一小部分工作
标签: perl mojolicious