Catalyst 5.8へのアップグレード

| コメント(0) | トラックバック(0)
会社の業務で使っているシステムのアップグレードをそろそろ手をつけなきゃなと思いつつ、どんどん時間が過ぎていった。
変更点などを大まかに頭に入れつつ、熟慮した結果が「作り直したほうが早い」だったため、先延ばしにしていたがそろそろ限界です。

「動いているものには手を出すな」が鉄則だけど、あとあとメンテナンスしなければいけなくなった時に古すぎて手の施しようもなくなってしまう可能性が高いからな・・・。

現状アップグレード後
Languageperl 5.8perl 5.12
FlameworkCatalyst 5.7Catalyst 5.8
Web ServerApache2Apache2
Application ServerApache2 + mod_perlStarman

一番大きいな変化はMooseベースになったことと、使っていたPluginなどの多くが非推奨になっていること。
ビジネスロジック自体は変える必要がないが、土台だけをきれいサッパリかえることにする。
Catalystの5.8へのアップグレードはTest::WWW::Mechanizeがうまく入らなかった以外はほぼノンストップでいけた。
Apache2 + mod_perlからStarmanにする際にCatalystをPSGI経由で起動するように変更するのだが、これが一癖あった。

StarmanはStart::Server経由で下記のような感じで起動してみる。

sudo /usr/local/bin/start_server \
    --port=PortNo \
    -- starman \
    --workers X \
    /path/to/MyApp.psgi

Myapp.pmでは@INCから見つけられない、Myapp.psgiでは設定ファイルが見つからないというエラーになる。
どちらもFindBinモジュールで現在のPath情報を取得して、その位置から相対的に自分のモジュールのパスや設定ファイルの位置を指定していた。

エラー出力をみてみると、どうやら/usr/local/binが入っている。もしや・・・。

$ file /usr/local/bin/start_server
/usr/local/bin/start_server: a /usr/local/bin/perl script text executable

start_server自体が最初にKickされるperlのスクリプトなので、start_serverの位置が入ってしまったということか・・・。
このままでは本番環境やテスト環境によってプロジェクトのパスが変わるたびに内容を書き換えないといけなくなってしまう。

Cwd::getcwdなどでも現在のパス情報を取得できなかったため、起動スクリプトでhostnameで振り分け、環境変数を経由してプロジェクトのルートのパスを渡すことにした。

hostnameでの切り分け部分
HOST=$(hostname)

if [ $HOST = 'production' ]; then
    HOME='/path/to/production/home'

elif [ $HOST = 'development' ]; then
    HOME='/path/to/development/home'

else
    echo "Please set infomation of host!"
    return 0

fi

start_serverの起動部分
sudo CATALYST_HOME=$HOME /usr/local/bin/start_server \
    --port=8080 \
    -- starman \
    --workers 5 \
    $HOME/script/MyApp.psgi &

それに伴い、MyApp.pmとMyApp.psgiのライブラリのパスと設定ファイルの位置も下記のように変更した。

MyApp.pm
__PACKAGE__->config('Plugin::ConfigLoader' =>
                    {file => "$ENV{CATALYST_HOME}/aquos-web.yml"});


MyApp.psgi
use lib "$ENV{CATALYST_HOME}/lib";
use aquos::Web;

最終的に下記のwikiを参考に、start_serverの起動スクリプトを作成し、MyApp.psgiはとりあえずアクセスログ、エラーログ、セッション、Basic認証を有効にして最小限の環境で開発をスタートしていくことにした。

starmanctl.sh
#!/usr/bin/env bash

PIDFILE='/tmp/start_server.pid'
START_SERVER=/usr/local/bin/start_server
APP=MyApp.psgi
PORT=8080
WORKERS=5
CATALYST_HOME=
HOME=
DEBUG=0 

check_host() {
    HOST=$(hostname)

    if [ $HOST = 'production' ]; then
        HOME='/path/to/production/home'

    elif [ $HOST = 'development' ]; then
        HOME='/path/to/development/home'
        DEBUG=1

    else
        echo "** Please set the infomation of this host!"
        exit 1

    fi
}

check_running() {
    [ -s $PIDFILE ] && sudo kill -0 $(cat $PIDFILE) >/dev/null 2>&1
}

_start() {

    sudo CATALYST_HOME=$HOME \
        CATALYST_DEBUG=$DEBUG \
        $START_SERVER \
        --port=$PORT \
        --pid-file=$PIDFILE \
        -- starman \
        --workers $WORKERS \
        $HOME/script/$APP &

    return 1
}

case "$1" in
    start)
        if check_running ; then
            echo "** Already running."
            exit 1;
        fi

        check_host

        _start
        ;;
    stop)
        sudo killall start_server
        ;;
    restart)
        sudo kill -HUP `cat $PIDFILE`
        ;;
     *)
        echo $"Usage: $0 {start|stop|restart}"
        exit 1
        ;;
esac

MyApp.psgi
#!/usr/bin/env perl

use strict;
use warnings;
use Plack::Builder;

use lib "$ENV{CATALYST_HOME}/lib";
use MyApp;

my $access_log = "$ENV{CATALYST_HOME}/script/log/access_log";
my $error_log  = "$ENV{CATALYST_HOME}/script/log/error_log";

# Main
MyApp->setup_engine('PSGI');
my $app = sub { MyApp->run(@_) };

# Extention
builder {
    my $logfh;
    open $logfh, ">>", $access_log or die $!;
    open STDERR, ">>", $error_log or die $!;
    $logfh->autoflush(1);

    enable "AccessLog", logger => sub { print $logfh @_ };
    enable "Auth::Basic", authenticator => \&authen_cb;
    enable 'Session';
    enable 'Debug';
    $app;
};

sub authen_cb {
    my($username, $password) = @_;
    return $username eq 'username' && $password eq 'password';
}

MyApp.pm(抜粋)
package MyApp;

use Moose;
use namespace::autoclean;

use Catalyst::Runtime 5.80;
                                                                                                                                                    
use Catalyst;
extends 'Catalyst';

our $VERSION = '0.01';

__PACKAGE__->config('Plugin::ConfigLoader' =>
                    {file => "$ENV{CATALYST_HOME}/aquos-web.yml"});

our @plugins = qw/                                                                                                                                                                 
                     ConfigLoader                                                                                                                                                  
                     Unicode                                                                                                                                                       
                     Unicode::Encoding                                                                                                                                             
                     Static::Simple                                                                                                                                                
                 /;

if ("$ENV{CATALYST_DEBUG}") {
    push(@plugins, 'Log::Colorful');
    push(@plugins, 'StackTrace');
}
                                                                                                                                                           
__PACKAGE__->setup(@plugins);

トラックバック(0)

トラックバックURL: http://blog.on-net.jp/mt/mt-tb.cgi/40

コメントする

2011年2月

    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28          

カテゴリ

アーカイブ