端的に言うと、
M.C.P.C.: Google ChromeウェブブラウザにMojolicious::LiteサーバからWebSocketで接続しリアルタイムでTwitterのストリームを表示する
M.C.P.C.: Google ChromeウェブブラウザにMojolicious::LiteサーバからWebSocketで接続しリアルタイムでTwitterのストリームをニコニコ動画風に表示する
に掲載してあったソースを、そのままAmazon EC2上に建てたCentOS 5.6の最小インストール環境に入れて、ソースにあるとおりのモジュールをcpanmで入れた状態にして、daemonとして起動して、いざTwitterのストリームを受信しようと思ったら、全く落ちてこないのです。
んで、このソース、もともとおかしいところがあって、AnyEventと、Mojolicious::Liteという2つのイベント駆動型モジュールで成り立っているのですが、Mojolicious::Liteのイベントループ開始しか存在していない。
んで、動く環境と動かない環境があるので、いろいろ考えてみたのですが、これらが動くためには、バックにイベントループが必要なのですが、そもそも様々なイベントループが提供されていて、それらの差異をなくすために用意されているのがAnyEventだということです。
そいう観点で見直してみると、AnyEventで現在使っているイベントループが何か、というのを保持している変数 $AnyEvent::MODEL というのがあるので、ストリームが流れてくるサーバと、流れないEC2のサーバでそれぞれ取得してみたら(Mojolicious::Liteのapp->start;の直前にprint $AnyEvent::MODEL."\n";を入れてみた)、
- ServersMan@VPS(常用): AnyEvent::Impl::EV
- EC2の素から入れた環境: AnyEvent::Impl::Perl
と表示されました。これは何を意味しているかというと、最初にテストしたServersMan@VPSの環境では、イベントループにEVというのを使っているのに対し、EC2の今回作った環境では、Pure Perlのループを使っていることです。
あと、AnyEventは、EVなど、高機能なイベントループ環境がある場合、自動的にそれを使います(use EV;しなくてもよい)。これが、動作不良の原因を見えにくくしていた原因でした。
というわけで、①cpanm EV で、EVをインストール、②念のため、use EV; をソースに入れておいて、EV がない環境で実行されないようにする、これで改良されました。
ただ、もう一方のMojolicious::LiteがEVに対応しているかどうかというのが調べきれなかったのですが、
MojoliciousとAnyEventを同時に利用する / Mojoliciousリファレンス - サンプルコードによるPerl入門
の中にリンクが張っているサンプルコードでは、まさしくAnyEventとMojolicious::Liteの共存が書かれていたので、いいんじゃねえかと思います。ともかく自分の想定している状況では動いているし。(いい加減だなー)
この状態で、AnyEventのcondvarの使い方がこれでいいのかどうか、というのが今持っている疑問点です。