2011 12月12日

PerlでPayPalのExpressCheckoutを実装するのにBusiness::PayPal::APIを使っているのだけれど、日本語(2byte文字)がうまく送信できない。

UTF-8で送ろうが、フラグ付きにしようが、だ。

散々悩んだ挙句、原因はSOAP::Liteが勝手にbase64エンコードするからだと判明。

Business::PayPal::APIは内部でSOAP::Liteを使用していて、Asciiだとそのままなのだけれど、それ以外はbase64にエンコードする仕様の様子。

前々から、例えば、OrderDescription に日本語を使うと上手くいかないと思っていたのだけれど、、、。
仕方がないから Business::PayPal::API::ExpressCheckoutをカスタマイズする。

/usr/lib/perl5/site_perl/5.8.8/Business/PayPal/API/ExpressCheckout.pm

Selec All Code:
    ## add all the other fields
    for my $field ( keys %types ) {
	next unless defined $args{$field};
 
        if( $field eq 'MaxAmount' ) {
            push @secrd, SOAP::Data->name( $field => $args{$field} )->type( $types{$field} )
              ->attr( {currencyID => $currencyID, xmlns => $self->C_xmlns_ebay} );
        }
        ## 追記ココから
        elsif($field eq 'Address'){
            my @addr;
            my $hash = $args{$field};
            for my $f ( keys %$hash) {
               push @addr,  SOAP::Data->name( $f )->type(string => $args{$field}{$f} );
            }
            my $obj = SOAP::Data->name( $field => \SOAP::Data->value( @addr ));
            push @secrd,$obj;
        }
        ## 追記ココまで
        else {
            push @secrd, SOAP::Data->name( $field => $args{$field} )->type( $types{$field} );
        }
    }

SOAPなんて使ってたらダメだね…









2011 11月28日

MojoliciousアプリケーションをCGIで動かす時に、スタイルシートや外部JavaScriptファイル、画像など静的ファイルの扱いには注意が必要になる。

これはテンプレートでタグヘルパーを使った時、例えば

Selec All Code:
    <%= stylesheet '/css/style.css' %>

とスタイルシートを読み込んだつもりだけど、これはスタイルシートを読み込むCGIを実行するのと同じ(スタイルシートのURLにリダイレクト処理するCGIとして実行される)
静的ファイルを呼び出す回数分のCGIが実行されることになるので、パフォーマンスも悪くなることは当然ながら、データベースの接続処理をstartup内でしていたりすると実行回数分の接続を行う事となる。

以前speedyCGIとしてMojoliciousアプリケーションを動作させていた時に、MySQLの最大同時接続数が異常になってMySQLサーバがダウンした事もある。

MojoliciousでCSSなどの静的ファイルを利用する – サンプルコードによるPerl入門

 ローカル環境で試験をするときは、組み込みのWebサーバーがCSSなどの静的ファイルをディスパッチしてくれるので、パフォーマンスの問題は起こりません。一方さくらのレンタルサーバーではCGIというプロトコルを利用してWebアプリケーションを起動しています。CGIというプロトコルはひとつのアクセスに対してひとつのプロセスを立ち上げます。プロセスの起動という処理はとても時間がかかるので、静的ファイルをCGIでディスパッチするとパフォーマンスの劣化が顕著に見られることになります。

リンク先にあるように、組み込みのwebサーバやその他のプリフォークサーバ(starman等)ならば問題ないのかもしれない。まぁ、それ自体がwebサーバとして動作するものなので当然といえば当然か。

CGIとして動作させる場合の解決策としてmod_rewriteの利用が提唱されている。.httaccess(またはhttpd.conf)でApacheが静的ファイルは静的ファイルとして処理するようにmod_rewriteルールを設定する。

もう一つ解決する方法としては、タグヘルパーを使わずに

Selec All Code:
    <link href="/css/style.css" media="screen" rel="stylesheet" type="text/css" />

などと直接タグを書いてしまう方法。これはデプロイするときにディレクトリ構成が変わったりすると後々面倒(テンプレートをすべて修正する必要があるとか)なので、推奨される方法ではないのかもしれないけれど。

MojoliciousをCGI動作させていてパフォーマンスがイマイチだな・・・と思っているなら調べてみるといいかもしれない。

App.pmとかのstartup()内に

Selec All Code:
sub startup {
    warn 'warn CGI run.';
    ....
}

等としてアプルケーションを実行するとapacheのエラーログに記録されるので1度の実行で複数行のログが残っていたらその行数分アプリケーションが実行されていることになる。

Apacheでデプロイする様々な方法

Apache deployment – GitHub
Apache/CGI にmod_rewriteの設定が記述されている。その中の Pretty “Web 2.0″ URLs という項目は参考になる。









2011 11月22日

Apatana Studioで何かのプラグインを追加したあたりから起動時に以下のようなエラーが出るようになった。

111121-0002

エラー内容:”Sending Ping…” 中に内部エラーが発生しました。
org/apache/derby/iapi/error/ShutdownException

ググッてみると、Apatana Usage をオフにするといいような発言があったので試してみる。
初期設定>一般>開始およびシャットダウン

111121-0003

Aptanaを再起動してみるもエラーが出る。

で、すべてのチェックを外して起動してみた。
エラーは出なくなった。かわりに初期設定が出来なくなった…orz。

結局クリーンインストール。
日本語化、テーマ変更(Eclipse Color Themes)、EPICをインストルしただけの状態の起動項目を記録しておく。
aptana初期 起動項目









2011 10月15日

configファイルの読み込み

設定ファイルを読み込む / Mojoliciousリファレンス – サンプルコードによるPerl入門

 設定(コンフィグ)ファイルを読み込むにはMojolicious::Plugin::Configを利用します。

というように、Mojoliciousアプリで設定ファイルを使う事ができる。例えば etc/MyApp.conf を読み込むには以下のような感じ。 stash_keyはオプションで設定できる(デフォルトはconfig?)

etc/MyApp.conf

Selec All Code:
{
    # MyApp config
 
    # サービス名
    SARVICE_NAME => 'hogehoge',
 
    # 配列のリファレンス等
    CATEGORY => [0,1,2,3,4],
}

MyApp.pm

Selec All Code:
package MyApp;
 
sub startup {
    my $self = shift;
 
    # コンフィグファイル読み込み
    my $config = $self->plugin('config', { file => 'etc/MyApp.conf', stash_key => 'conf' });
    ....
}

読み込みはリンク先に詳しく書かれている。

configで設定された値を使う

コントローラーとかで使う

Selec All Code:
sub index {
    my $self = shift;
 
    #my $config = $self->stash('conf');
    my $config = $self->config;
    my $service_name = $config->{SARVICE_NAME};
    # or 
    my $service_name = $self->config('SARVICE_NAME');
    ....
}

テンプレートで使う

Selec All Code:
    <%= stash('conf')->{SARVICE_NAME} %>
    <%= config->{SARVICE_NAME} %>
    <%= config('SARVICE_NAME') %>

オブジェクト指向的には config()で取得したほうがいいのかな?

テンプレートで使うには

Selec All Code:
<%= config 'SARVICE_NAME' %>

がタイプが一番少ないようだ。









2011 10月14日

すぐ忘れるし、どこにあったか分からなくなるのでメモ。

Mojolicious – GitHubより引用

Selec All Code:
    package MyApp;
 
    use Mojo::Base 'Mojolicious';
 
    use DBIx::Custom;
 
    has dbi => sub {
        my $dbi = DBIx::Custom->connect(...);
        return $dbi;
    };
 
    sub startup {
        my $self = shift;
 
        ### YOU MUST NOT CALL dbi() method in starup().
    }

リンク先にはBad Exampleもあるので参考に。