【问题标题】:Mojo IOLoop blocks app when ranMojo IOLoop 在运行时会阻止应用程序
【发布时间】: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


【解决方案1】:

你是说它会休眠$sleep_time 秒吗?因为这不是它应该如何工作的。它应该退出并在下次recurring 启动它时继续该过程。实际上,每次recurring 启动时,您都试图启动该任务的另一个副本,并且您的任务可能因为无法启动多个任务而挂起?只是猜测,它是否曾经从$sync->run() 返回? $sync 是什么东西? ——鲍罗丁

是的,似乎是因为中间的睡眠,谢谢!关于在调用外部资源时如何友好而不是一次性挤奶的任何建议? :P – a7omiton

是的,您需要一个类似的 recurring 计时器,但在每个步骤中只做一小部分工作 ——鲍罗丁

【讨论】:

    猜你喜欢
    • 2017-10-07
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    • 2022-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多