【问题标题】:mojolicious does not work in non-blocking waymojolicious 不能以非阻塞方式工作
【发布时间】:2014-08-07 10:05:11
【问题描述】:

首先,对不起,我英语不好。

我正在制作一个 Mojolicious 应用程序。

我的控制器使用 Mojo::UserAgent 完成一些工作,并在输出时使用结果。

my $ua = Mojo::UserAgent->new();
my $tx = $ua->head( $location );
my $result;

if ( $tx->res->code eq '200' ) {
    $result = 'good';
}
else {
    $result = 'bad';
}

# pass the result to the renderer's stash
$self->render( result => $result );

此代码运行良好。 它适用于我的本地机器和服务器

接下来,我尝试使$ua->head() 成为非阻塞方式,因为它可能需要很长时间才能完成。 (我是新手,这是我第一次尝试使用 Mojo 的非阻塞代码,供大家参考)

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

$self->render_later;
$ua->head( $location => sub {
    my ($ua, $tx) = @_;

    if ( $tx->res->code eq '200' ) {
        $result = 'good';
    }
    else {
        $result = 'bad';
    }
    $self->render( result => $result );
});
Mojo::IOLoop->start unless Mojo::IOLoop->is_running;

这种方法也适用于我的本地机器(MacBook OSX 10.9.4、Perl 5.18、Standalone using morbo)。

但是,当我在服务器中启动此代码时,服务器会响应“404 not found”。

此服务器使用 Nginx 代理,将请求转发到工作节点。

browser -- Nginx -- Mojolicious App

所以,我猜这个代理与我的问题有关,但我不知道如何解决它。我什至不知道我必须从哪里开始找到确切的原因。

任何建议将不胜感激。

附:我应该说“阻塞方法”在我的本地机器和服务器上都很好用。只有“非阻塞方法”显示了这个问题。

Update (2014-08-21) : 我的一位精通 Perl 工程师的朋友跟我说,这似乎是 Mojo 的事件循环和 PSGI 的事件循环之间的问题,即类似兼容性的问题问题。我现在听不懂他在说什么,但我正在努力学习更多。

【问题讨论】:

    标签: perl nginx mojolicious


    【解决方案1】:

    来自Mojolicious Cookbook

    upstream myapp {
      server 127.0.0.1:8080;
    }
    server {
      listen 80;
      server_name localhost;
      location / {
        proxy_pass http://myapp;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto "http";
      }
    }
    

    【讨论】:

    • 感谢您的回复。但是,已经使用这种配置设置了服务器。我应该说“阻塞方式”在服务器和我的本地机器上都很好用。只有非阻塞方法没有。 :'(
    【解决方案2】:

    我认为代理运行良好,因为您有 http 404(不是 http 502 或其他)。

    您也必须在 morbo 下运行您的服务器 mojolicious 应用程序并使用“打印”调试您的应用程序。

    我认为您的控制器的动作未找到或未找到模板。

    顺便问一下,$self->render(result = $result) 是什么? 可能你想写$self->render(result => $result)

    因此,如果这是您的问题,那么要检测此错误,您应该查看 log/development.conf 或 log/production.conf 或在运行应用程序的控制台中。


    更新。

    我不知道问题出在哪里,但是这段代码可以正常工作。

      my $result;
    
      $self->render_later;
      $self->ua->head('http://ya.ru' => sub {
          my ($ua, $tx) = @_;
    
          print $self->dumper($ua);
    
    
          if ( $tx->res->code eq '200' ) {
              $result = 'good';
          }
          else {
              $result = 'bad';
          }
          sleep 2;
          $self->render( data => $result );
      });
      Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
    

    所以,$ua 变量从控制器 $self 中使用。所以,垃圾收集器回调调用时可能会破坏。 当你使用$self->ua->... 然后ua 对象保存在共享变量中,所以垃圾收集器不会破坏它。 非常有趣的例子。谢谢。

    【讨论】:

    • 感谢您的指点。这只是我在简化代码以在此处发布时犯的错字。
    猜你喜欢
    • 2015-07-19
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-01
    • 2015-03-31
    • 1970-01-01
    相关资源
    最近更新 更多