mojolicious不能以非阻塞的方式工作

时间:2014-08-07 10:05:11

标签: perl nginx mojolicious

起初,我很抱歉我不擅长英语。

我正在制作一个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尝试非blok代码,供您参考)

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”。

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

browser -- Nginx -- Mojolicious App

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

任何建议都将受到赞赏。

P.S。我应该说“阻塞方法”在我的本地机器和服务器上运行良好。只有“非阻塞方法”才能显示此问题。

更新(2014-08-21):我的一位技术娴熟的Perl工程师告诉我,这似乎是Mojo的事件循环与PSGI的事件循环之间的问题,即兼容性之类的问题问题。我无法理解他目前说的话,但我正在努力学习更多。

2 个答案:

答案 0 :(得分:0)

来自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";
  }
}

答案 1 :(得分:0)

我认为代理很有效,因为你有http 404(不是http 502或其他东西)。

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

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

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

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


UPD。

我不知道,问题出在哪里,但这段代码运行良好。

  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对象保存在共享变量中时,垃圾收集器不会销毁它。 非常有趣的例子。感谢。