Mojolicious应用程序中的并行请求 [英] Parallel requests in Mojolicious application

查看:201
本文介绍了Mojolicious应用程序中的并行请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有perl应用程序,例如,在Google中进行并行搜索:

use Mojo::UserAgent;
use Mojo::IOLoop;

my $ua = Mojo::UserAgent->new();

my $delay = Mojo::IOLoop->delay(sub { say 'DONE1 (should be before render)'; });

foreach my $i ( 1 .. 10 ) {
    $delay->begin();

    $ua->get("http://www.google.ru/search?q=$i" => sub {
        say $i;
        $delay->end();
    });
}

$delay->wait() unless $delay->ioloop->is_running();

say 'DONE2 (should be before render)';
say 'Found! (render)';

效果很好:

6
1
7
10
3
9
2
5
8
4
DONE1 (should be before render)
DONE2 (should be before render)
Found! (render)

当我在控制器的Mojolicious应用程序中使用此代码时:

package MyApp::Google;

use Mojo::Base 'Mojolicious::Controller';

sub search {

    my $self = shift;

    my $delay = Mojo::IOLoop->delay(sub { $self->app->log->debug('DONE1 (should be before render)') });

    foreach my $i ( 1 .. 10 ) {
        $delay->begin();

        $self->ua->get("http://www.google.ru/search?q=$i" => sub {
            $self->app->log->debug($i);
            $delay->end();
        });
    }

    $delay->wait() unless $delay->ioloop->is_running();

    $self->app->log->debug('DONE2 (should be before render)');

    return $self->render_text('Found!');

}

这是错误的方式:

[Wed May 15 11:07:32 2013] [debug] Routing to controller "MyApp::Google" and action "search".
[Wed May 15 11:07:32 2013] [debug] DONE2 (should be before render)
[Wed May 15 11:07:32 2013] [debug] 200 OK (0.005689s, 175.778/s).
[Wed May 15 11:07:32 2013] [debug] 1
[Wed May 15 11:07:32 2013] [debug] 8
[Wed May 15 11:07:32 2013] [debug] 10
[Wed May 15 11:07:32 2013] [debug] 5
[Wed May 15 11:07:32 2013] [debug] 3
[Wed May 15 11:07:32 2013] [debug] 9
[Wed May 15 11:07:32 2013] [debug] 6
[Wed May 15 11:07:32 2013] [debug] 2
[Wed May 15 11:07:32 2013] [debug] 4
[Wed May 15 11:07:32 2013] [debug] 7
[Wed May 15 11:07:32 2013] [debug] DONE1 (should be before render)

我想$delay->wait() 没有等待.为什么会这样?

解决方案

在这种情况下,您需要通过从控制器调用方法 render_later 来禁用自动渲染. ( http://mojolicio.us/perldoc/Mojolicious/Controller#render_later )

只需将下一个字符串添加到 search 控制器:

$self->render_later;

完整示例:

#!/usr/bin/perl -wl
use Mojolicious::Lite;

get '/' => sub {
    my $self = shift;
    $self->render_later;
    my $delay = Mojo::IOLoop->delay(sub {
        $self->app->log->debug('Delay finished!');
        $self->render(text => 'test!');
    });
    for my $i (0 .. 5) {
        my $end = $delay->begin;
        Mojo::IOLoop->timer($i => sub {
            $self->app->log->debug($i);
            $end->();
        });
    }
};

app->start;

I have perl application which, for example, parallel searching in google:

use Mojo::UserAgent;
use Mojo::IOLoop;

my $ua = Mojo::UserAgent->new();

my $delay = Mojo::IOLoop->delay(sub { say 'DONE1 (should be before render)'; });

foreach my $i ( 1 .. 10 ) {
    $delay->begin();

    $ua->get("http://www.google.ru/search?q=$i" => sub {
        say $i;
        $delay->end();
    });
}

$delay->wait() unless $delay->ioloop->is_running();

say 'DONE2 (should be before render)';
say 'Found! (render)';

And it's works fine:

6
1
7
10
3
9
2
5
8
4
DONE1 (should be before render)
DONE2 (should be before render)
Found! (render)

When I use this code in Mojolicious application in controller:

package MyApp::Google;

use Mojo::Base 'Mojolicious::Controller';

sub search {

    my $self = shift;

    my $delay = Mojo::IOLoop->delay(sub { $self->app->log->debug('DONE1 (should be before render)') });

    foreach my $i ( 1 .. 10 ) {
        $delay->begin();

        $self->ua->get("http://www.google.ru/search?q=$i" => sub {
            $self->app->log->debug($i);
            $delay->end();
        });
    }

    $delay->wait() unless $delay->ioloop->is_running();

    $self->app->log->debug('DONE2 (should be before render)');

    return $self->render_text('Found!');

}

It is going in a wrong way:

[Wed May 15 11:07:32 2013] [debug] Routing to controller "MyApp::Google" and action "search".
[Wed May 15 11:07:32 2013] [debug] DONE2 (should be before render)
[Wed May 15 11:07:32 2013] [debug] 200 OK (0.005689s, 175.778/s).
[Wed May 15 11:07:32 2013] [debug] 1
[Wed May 15 11:07:32 2013] [debug] 8
[Wed May 15 11:07:32 2013] [debug] 10
[Wed May 15 11:07:32 2013] [debug] 5
[Wed May 15 11:07:32 2013] [debug] 3
[Wed May 15 11:07:32 2013] [debug] 9
[Wed May 15 11:07:32 2013] [debug] 6
[Wed May 15 11:07:32 2013] [debug] 2
[Wed May 15 11:07:32 2013] [debug] 4
[Wed May 15 11:07:32 2013] [debug] 7
[Wed May 15 11:07:32 2013] [debug] DONE1 (should be before render)

I guess so $delay->wait() is not waiting. Why is it going?

解决方案

In this case you need to disable automatic rendering by calling method render_later from the controller. (http://mojolicio.us/perldoc/Mojolicious/Controller#render_later)

Just add the next string to search controller:

$self->render_later;

Complete example:

#!/usr/bin/perl -wl
use Mojolicious::Lite;

get '/' => sub {
    my $self = shift;
    $self->render_later;
    my $delay = Mojo::IOLoop->delay(sub {
        $self->app->log->debug('Delay finished!');
        $self->render(text => 'test!');
    });
    for my $i (0 .. 5) {
        my $end = $delay->begin;
        Mojo::IOLoop->timer($i => sub {
            $self->app->log->debug($i);
            $end->();
        });
    }
};

app->start;

这篇关于Mojolicious应用程序中的并行请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆