ArkをCGIで動かす場合の、アクセス先のスクリプトとApacheの.htaccess(ないしhttpd.conf)の記述方法です。基本的にはCatalystと同じですね。
ただし、後述しますが、$c->uri_forではまっています。
/bin/amikeco_cgi.pl
まずはmyapp_cgi.plから。
#! /usr/local/bin/perl
use 5.008_000; # Encode周りを考えると5.8.1以上がいいです
use strict;
use warnings;
use utf8;
use FindBin;
use lib $FindBin::RealBin . '/../lib'; # /bin/../libを意味します
use Amikeco::Web; # MyAppです
use HTTP::Engine::Middleware;
use HTTP::Engine;
my $app = Amikeco::Web->new;
$app->setup_minimal; # CGI版の場合、動的ロードのためsetupメソッドの代わりに使います
my $mw = HTTP::Engine::Middleware->new;
$mw->install('HTTP::Engine::Middleware::Static' => {
docroot => $app->path_to('root'),
regexp => '/(?:(?:css|js|img|images?|swf|static|tmp|)/.*|[^/]+\.[^/]+)',
});
HTTP::Engine->new(
interface => {
module => 'CGI', # 'ServerSimple'などの代わりに、CGIを指定します
args => {
# ポート番号などにこだわりがなければ、自分のホストの80番で受けます
},
request_handler => $mw->handler( $app->handler ),
},
)->run;
__END__
基本的にはark server MyAppコマンドで動くArk::Command::Serverをコピペして、必要なところだけ直すといった感じです。過不足があるかも知れませんが、これで動いてはいます。
use Amikeco::Web;がuse MyApp;なのは上記の通りですが、これは『モダンPerl入門』などにあるように、以下ような階層にしたためです(同書のAPIがLogicです)。
Amikeco
Auxiliary
Web
Controller
Model
View
CLI
Controller
View
Logic
Schema
...etc
httpd.confまたは.htaccess
XREA, XREA+, Coreserverを想定していますが、基本的にさくらなどでも一緒です。
<IfModule rewrite_module>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/?bin/amikeco_cgi.pl
RewriteRule ^(.*)$ /bin/amikeco_cgi.pl/$1 [PT,L]
</IfModule>
上記は参考にさせていただいた
の、ほとんどそのままですね。
このように、ArkはCatalystのノウハウが通用する場合があるので、Catalystが得意な人も、CatalystをArkで勉強しようとする人も、遊んでみると面白いのではないかと思います。
速度は十分に満足できます
では速度はどうでしょうか。
単にテンプレートをText::MicroTemplateで表示するだけなら、ServerSimple時と余り変わらずに表示できます。しかし、ちょっとModelを触ったりするとData::ModelやDBIx::Class(今回は前者を使っています)を呼ぶでしょうし、さらにData::LocalizerやらHTML::Shakanやら諸々のモジュールを呼ぼうとすると、先にちょっと言及した簡単なlist_all_worldsアクションであっても、ほぼ2秒程度掛かります。
流石にServerSimpleやFastCGIなどと比べてはもっさり感がありますが、それでも十分に現実的な範囲とは言えるかも知れません。その差はひとえにモジュールの大量のロード時間に起因するものですので、例えばCRUDのうちRでなくC,U,Dの処理をしたとしても、これが線形に遅くなるわけではありません。
$c->uri_forに問題が......
ところが困ったことに、$c->uri_forの絶対パスが問題になります。/world/にアクセスすると確かにワールド(ゲームサーバー)一覧を表示するlist_all_worldsを呼べるのですが、リンク先に$c->uri_for(sprintf '/world/%s/', $s->{world})を指定した場合に、/world/bahamut/などではなく/world/amikeco_cgi.cgi/world/bahamut/になってしまうのです。
勿論動くことには動きますが、流石にこれではまっとうなURIではないので、ちゃんとした指定方法を考えたいと思います。
./%s/などとすると、/world(最後のスラッシュなし)の場合に/bahamut/になるので、いっそsprintf '%s%s/', $c->res->uri . ($c->{base_uri} =~ m{ / \z }xms ? '' : '/'), $->{world}などとした方が良いかも知れませんね。
追記:アクションキャッシュの取り扱いなどについて言及した続編が(トラックバックとして)あります。
コメントする