新しいblogに移行しました

新ブログ "All Yout Bugs Are Belong To Ass" に移行しました!

2011-04-28

[Linux]ユーザ権限でsvscanbootを立ち上げて色々exportする手間を省く

何が嬉しいか

僕がやっている限りですが、perlbrew環境でもdaemontoolsのrunファイルで色々exportしなくても意図した通りにアプリケーションが動作してくれる、という点が挙げられます。

設定

例えば$HOME/service/myappとかつくって、PSGI-appをdaemontoolsで常駐させたい場合。

$HOME/.bashrcに1個exportを追記する

以下の行を追記しておく。
export PATH=$HOME/bin:$PATH
書いたら、一旦ログインし直す。

$HOME/以下に必要なディレクトリを用意する

~$ mkdir -p ~/service ~/bin ~/myapp/log

ユーザ用のsvscanbootを作る


$HOME/bin/svscanboot

#!/bin/sh

svscan $HOME/service 2>&1 | \
  readproctitle $HOME/service errors: ................................................................................................................................................................................................................................................................................................................................................................................................................ 

runファイルを作る


$HOME/service/myapp/run

#!/bin/sh
exec 2>&1
start_server --port=6000 -- plackup -L Shotgun -s Starlet ~/psgi/myapp/myapp.psgi

$HOME/service/myapp/log/run

#!/bin/sh
exec 2>&1
exec multilog t ~/myapp/log

サービスをdaemontoolsに登録する

~$ mv ~/myapp ~/service/ -v

svscanbootを起動する

~$ svscanboot &
[1] 13787
プロセス番号(ここでは13787)を控えておき、これをdisownする。
~$ disown 13787

ps axfhでプロセスを見ると、大体こんな感じになってると思います。

~$ ps axfh
  :
  :
 省略
  :
  :
13787 ?        S      0:00 /bin/sh /home/ytnobody/bin/svscanboot
13788 ?        S      0:00  \_ svscan /home/ytnobody/service
17896 ?        S      0:00  |   \_ supervise api
19351 ?        S      0:00  |   |   \_ /bin/sh ./run
19352 ?        S      0:00  |   |       \_ /home/ytnobody/perl5/perlbrew/perls/perl-5.12.3/bin/perl /home/ytnobody/perl5/perlbrew/perls/current/bin/start_server --port=6000 -- plackup -L Shotgun -s Starl
19353 ?        S      0:00  |   |           \_ /home/ytnobody/perl5/perlbrew/perls/perl-5.12.3/bin/perl /home/ytnobody/perl5/perlbrew/perls/current/bin/plackup -L Shotgun -s Starlet /home/ytnobody/myapp
19354 ?        S      0:00  |   |               \_ /home/ytnobody/perl5/perlbrew/perls/perl-5.12.3/bin/perl /home/ytnobody/perl5/perlbrew/perls/current/bin/plackup -L Shotgun -s Starlet /home/ytnobody/my
19355 ?        S      0:00  |   |               \_ /home/ytnobody/perl5/perlbrew/perls/perl-5.12.3/bin/perl /home/ytnobody/perl5/perlbrew/perls/current/bin/plackup -L Shotgun -s Starlet /home/ytnobody/my
19356 ?        S      0:00  |   |               \_ /home/ytnobody/perl5/perlbrew/perls/perl-5.12.3/bin/perl /home/ytnobody/perl5/perlbrew/perls/current/bin/plackup -L Shotgun -s Starlet /home/ytnobody/my
19357 ?        S      0:00  |   |               \_ /home/ytnobody/perl5/perlbrew/perls/perl-5.12.3/bin/perl /home/ytnobody/perl5/perlbrew/perls/current/bin/plackup -L Shotgun -s Starlet /home/ytnobody/my
19358 ?        S      0:00  |   |               \_ /home/ytnobody/perl5/perlbrew/perls/perl-5.12.3/bin/perl /home/ytnobody/perl5/perlbrew/perls/current/bin/plackup -L Shotgun -s Starlet /home/ytnobody/my
19359 ?        S      0:00  |   |               \_ /home/ytnobody/perl5/perlbrew/perls/perl-5.12.3/bin/perl /home/ytnobody/perl5/perlbrew/perls/current/bin/plackup -L Shotgun -s Starlet /home/ytnobody/my
19360 ?        S      0:00  |   |               \_ /home/ytnobody/perl5/perlbrew/perls/perl-5.12.3/bin/perl /home/ytnobody/perl5/perlbrew/perls/current/bin/plackup -L Shotgun -s Starlet /home/ytnobody/my
19361 ?        S      0:00  |   |               \_ /home/ytnobody/perl5/perlbrew/perls/perl-5.12.3/bin/perl /home/ytnobody/perl5/perlbrew/perls/current/bin/plackup -L Shotgun -s Starlet /home/ytnobody/my
19362 ?        S      0:00  |   |               \_ /home/ytnobody/perl5/perlbrew/perls/perl-5.12.3/bin/perl /home/ytnobody/perl5/perlbrew/perls/current/bin/plackup -L Shotgun -s Starlet /home/ytnobody/my
19363 ?        S      0:00  |   |               \_ /home/ytnobody/perl5/perlbrew/perls/perl-5.12.3/bin/perl /home/ytnobody/perl5/perlbrew/perls/current/bin/plackup -L Shotgun -s Starlet /home/ytnobody/my
17897 ?        S      0:00  |   \_ supervise log
17900 ?        S      0:00  |       \_ multilog t /home/ytnobody/myapp/log
/home/ytnobody/src/mongodb/data/db --nohttpinterface
  :
  :
 省略
  :
  :

2011-04-27

[Nginx]フォワードプロキシを構築する

ここを参考に、俗に言う串をNginxで構築しました。

nginx.conf

http {

    ### google DNS
    resolver 8.8.8.8;

    server {
        listen 80;
        server_name proxy.mydomain.net;
        location / {
            proxy_pass $scheme://$http_host$request_uri;
        }
    }

}

schemeとhttp_host,requet_uriを使いまわすのがポイントですね。

2011/5/16 追記
httpsについては、このフォワードプロキシを通すことで、まともにアクセスできなくなる可能性があります。

2011-04-26

[Perl]Hachioji.pm #4

4/23(土)に開催されたHachioji.pm #4に参加してきました!

ぼくが記事を書く頃には大体いつも、皆さんきっちりと記事を書いてくれてますので、僕は雰囲気を伝える方向に専念できます><

ひどい雨にもかかわらず・・・

当日はかなりどしゃ降りの雨だったのですが、なんとATNDで参加表明していた13名が全員参加。さすがHachioji.pm、毎度のことながら出席率の高さがハンパ無いです。

Hachioji.pm =~ Gourmet.pm ???

さて、これまでのHachioji.pm開催会場となったお店を振り返ってみますと・・・(※以下、ATNDへのリンク)
#0 会場 八王子駅南口 あじこ家(沖縄料理)
#1 会場 魚米 八王子店(海鮮料理)
#2 会場 八王子北口 多熱食房(中華料理)
#3 会場 タイ料理レストラン タイラーンナー(タイ料理)
・・・と、かなりグルメな選定となっています。uzullaさんのチョイスが光っているのが良くわかりますね!
そして、今回の会場は南米ペルー料理 MISKY(ペルー料理)。もう八王子だけで世界の料理が堪能できそうな勢いですね!

「makamakaさんが登場したら拍手で迎えてください!」

これはHachioji.pmでの恒例儀式のようなものですね!makamakaさんはお仕事の都合もあって遅刻せざるを得ないのですが、そんな彼を労うべく(?)皆で大きな拍手で迎えましたw
「到着おめでとうございます!」
雨ということもあって、心なしかmakamakaさんの顔に疲れの表情が見え隠れしていたようにも見えましたけどね!><

ustreamもリアルタイムつぶやきもない

そりゃあそうです。だって、みんな呑んで食ってしてるんですものw

まったりした空気の中で恒例のA4-LT

飲み食いしてるので、みなさんそりゃあもうまったりしてました。そんな中LTが執り行われたわけですが、掻い摘んで印象に残ったものについて取りあげます。
今回のテーマは「最近作ったもの or GW中につくりたい物」です。

GANCってなんだーーーーー!!!

まず印象に残ったのがmgikenさんの「LAMPではなくGANC」のお話でした。Gentoo(Linux), Arc(関数型プログラミング言語), Nginx(Webサーバ), CouchDB(NOSQLデータストア)の頭文字を取って「GANC(がんく)」だそうです。
Gentoo、Arcあたりの話をすると、たいていの人はその先の話を聞いてくれなくなるそうなので、今回はCouchDBのViewサーバをArcでつくったよ!という話に的を絞ってました。

Dropboxでblogを管理

su_askaさんの「Dropboxでblog/wikiを管理する」お話。「Perl MongerなのにPukiwikiやWordPress使ってるのはおかしいだろう」という信念から、DropboxにMarkdownファイルを置いてblogとwikiを更新するようにしたというのですが、管理ツールいらずという謳い文句が琴線に触れるものがあります。

ハリセンメソッド

サブタイトル見ただけで誰のLTなのかある程度想像できる人もいると思いますが、「期待を裏切らない男」makamakaさんによる斬新なプレゼン手法です!


これはequinox79さんによる撮影ですが、これを見てLTの資料だと思う人はそう多くはないでしょう。

最近作ったサービスについて発表しました

ぼくの発表では、個人的な欲求に則って作ったサービス「dossug」について話しました。
LT資料はこちら

2011-04-22

[Perl]Test-WWW-Mechanize-1.30のテストがこける

こんな風にこけました@perl-5.12.3
~/$ cpanm Test::WWW::Mechanize
--> Working on Test::WWW::Mechanize
Fetching http://search.cpan.org/CPAN/authors/id/P/PE/PETDANCE/Test-WWW-Mechanize-1.30.tar.gz ... OK
Configuring Test-WWW-Mechanize-1.30 ... OK
==> Found dependencies: Test::LongString, WWW::Mechanize, HTML::TreeBuilder, HTTP::Server::Simple, Carp::Assert::More, HTTP::Server::Simple::CGI
--> Working on Test::LongString
Fetching http://search.cpan.org/CPAN/authors/id/R/RG/RGARCIA/Test-LongString-0.15.tar.gz ... OK
Configuring Test-LongString-0.15 ... OK
Building and testing Test-LongString-0.15 ... OK
Successfully installed Test-LongString-0.15
--> Working on WWW::Mechanize
Fetching http://search.cpan.org/CPAN/authors/id/J/JE/JESSE/WWW-Mechanize-1.68.tar.gz ... OK
Configuring WWW-Mechanize-1.68 ... OK
==> Found dependencies: HTML::TreeBuilder, HTTP::Server::Simple, HTTP::Server::Simple::CGI
--> Working on HTML::TreeBuilder
Fetching http://search.cpan.org/CPAN/authors/id/J/JF/JFEARN/HTML-Tree-4.2.tar.gz ... OK
Configuring HTML-Tree-4.2 ... OK
Building and testing HTML-Tree-4.2 ... OK
Successfully installed HTML-Tree-4.2
--> Working on HTTP::Server::Simple
Fetching http://search.cpan.org/CPAN/authors/id/J/JE/JESSE/HTTP-Server-Simple-0.44.tar.gz ... OK
Configuring HTTP-Server-Simple-0.44 ... OK
Building and testing HTTP-Server-Simple-0.44 ... OK
Successfully installed HTTP-Server-Simple-0.44
Building and testing WWW-Mechanize-1.68 ... OK
Successfully installed WWW-Mechanize-1.68
--> Working on Carp::Assert::More
Fetching http://search.cpan.org/CPAN/authors/id/P/PE/PETDANCE/Carp-Assert-More-1.12.tar.gz ... OK
Configuring Carp-Assert-More-1.12 ... OK
Building and testing Carp-Assert-More-1.12 ... OK
Successfully installed Carp-Assert-More-1.12
Building and testing Test-WWW-Mechanize-1.30 ... FAIL
! Installing Test::WWW::Mechanize failed. See /home/ytnobody/.cpanm/build.log for details.

で、ここ見る限り、Test-LongString-0.15がダメっぽいので、Test-LongString-0.14をいれてからT::W::Mech入れればいいっぽいです。

~/$ cpanm http://search.cpan.org/CPAN/authors/id/R/RG/RGARCIA/Test-LongString-0.14.tar.gz
--> Working on http://search.cpan.org/CPAN/authors/id/R/RG/RGARCIA/Test-LongString-0.14.tar.gz
Fetching http://search.cpan.org/CPAN/authors/id/R/RG/RGARCIA/Test-LongString-0.14.tar.gz ... OK
Configuring Test-LongString-0.14 ... OK
Building and testing Test-LongString-0.14 ... OK
Successfully installed Test-LongString-0.14
~/$ cpanm Test::WWW::Mechanize
--> Working on Test::WWW::Mechanize
Fetching http://search.cpan.org/CPAN/authors/id/P/PE/PETDANCE/Test-WWW-Mechanize-1.30.tar.gz ... OK
Configuring Test-WWW-Mechanize-1.30 ... OK
Building and testing Test-WWW-Mechanize-1.30 ... OK
Successfully installed Test-WWW-Mechanize-1.30

追記
どうやら、これ以外の原因でコケる場合もある模様。
とりあえずCPANRTではなくgoogle codeにて不具合等を管理しているようなので、そちらもご参照を。

2011-04-19

[Linux]Titanium Mobile 1.2.2をUbuntu10.10-i386に入れた

基本的な手順としては、こちらのサイトの通りに進めました。
しかし、Titanium Developerの起動時の手順で問題が発生。以下の様な手順で問題を回避しました。

Titanium Developerのディレクトリのリネーム

これをやらないと、まともに起動できません。
~$ mv Titanium\ Developer-1.2.2/ ~/.titanium

runtime以下に各種同梱ライブラリ群を移動

次に、ライブラリ群を$HOME/.titanium/runtime/linux/1.0.0/ から $HOME/.titanium/runtime/ へと移動させてしまいます。
~$ mv ~/.titanium/runtime/linux/1.0.0/* ~/.titanium/runtime/

ちなみにこれでもまだ
~$ ~/.titanium/Titanium\ Developer 
/home/ytnobody/.titanium/Titanium Developer: symbol lookup error: /usr/lib/libgtk-x11-2.0.so.0: undefined symbol: g_malloc_n

といわれ、起動できません。Titanium + Ubuntuのマリアージュまでの道のりは、なかなか険しいですな。

衝突している同梱ライブラリを削除する

前述のエラーでググれば情報が出てくるのですが、要するに$HOME/.titanium/runtime/配下にあるライブラリのうち、
  • libgobject2.0
  • libglib2.0
  • libgio2.0
  • libgthread2.0
この4種のライブラリが衝突しているから起動できないのだそうです。コイツらを削除してやることで、無事にTitanium Developerを起動する事ができました。
~$ rm ~/.titanium/runtime/libgobject-2.0.* -f
~$ rm ~/.titanium/runtime/libglib-2.0.* -f
~$ rm ~/.titanium/runtime/libgio-2.0.* -f
~$ rm ~/.titanium/runtime/libgthread-2.0.* -f
~$ ~/.titanium/Titanium\ Developer 

ちなみに起動時に
icedteanp plugin error: Failed to run /etc/alternatives/../../bin/java. For more detail rerun "firefox -g" in a terminal window.
といわれます。今のところ正常に動作しているようなのであまり気にしていないのですが、これは大丈夫なのでしょうかねえ。。。

追記

android-sdkのパスを指定してもエラーが出てプロジェクトが作れない時の対処

いざ、新規プロジェクトを立ち上げようとして、プロジェクト種別「Mobile」を選択した際、「android-sdkの場所を教えてくんな」と言ってきます。この時、正常なandroid-sdkのパスを指定しても
Couldn't find adb or android in your SDK's "tools" directory. You may need to install a newer version of the SDK tools.
とか言われてしまいました。そんな時は、
~$ ln -s ~/android-sdk-linux_x86/platform-tools/adb ./android-sdk-linux_x86/tools/
とすればOKでした。

2011-04-15

[Forth]perlでいうところのrequireをしたい

include hoge.fth
のように、includeを使うか、
s" ./lib/hoge.fth" included
のように、includedワードでスタック内の文字列に該当するソースファイルを指定するかの2方式を選べるみたいです。
どちらの場合も、プログラムが置かれているディレクトリを元にソースファイルの場所を指定する必要があります。

追記
Ubuntu 10.04 LTSの場合、/usr/share/gforth 配下にgforthのモジュール群があったので、これもrequireできるみたいです。
従って、libパスは ./ および /usr/share/gforth ということになります。

[Forth]gforthをCGIとして動かす場合のshebangの書き方

こちらのフォーラムの情報をもとに試したところ、
#! /usr/bin/env gforth
としてやればOKです。

[Forth]スタックに乗ってる文字列を複製してみる

えーとforthについてはほぼ初心者の域をでないのですが、時折触ってみては「いつかは使いこなしたい」と思っている言語のひとつです。

そんなforth学習の一環として、手始めに
・ワード定義
・スタック操作
・文字列操作(?)
あたりを一気にやってみたので、メモを残しておきます。
: ddup ( a b -- a b a b )
    over over
;

s" ほげ" ddup
type type cr
bye

$ gforth hoge.fth 
ほげほげ

2011-04-14

[Linux]さくらVPSにてMongoDBを一般ユーザ権限で動かす

MongoDBにすこし興味が出たので、このページを参考に、さくらVPS(CentOS 5.5)で動かしてみました。root無くても動かせそうだったので、ユーザ権限で動かすことにしました。

ユーザ権限で動かすので、その用意。

$HOMEにいろいろどっ散らかるのはイヤなので、$HOME/srcを作って、そこにMongoDBを置くことにしました。
~ $ mkdir ~/src

MongoDBの入手

こちらのサイトにLinux 64-bit向けのtarボールがあるので、おすすめ(recommended)と書かれてるバージョンのをwgetで引っ張ってきます。
~ $ wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-1.8.1.tgz

インストール

$HOME/srcにtarボールを移動して、そこで解凍します。
~ $ mv mongodb-linux-x86_64-1.8.1.tgz ~/src/
~ $ cd ~/src
~/src $ tar zxvf mongodb-linux-x86_64-1.8.1.tgz
~/src $ ln -s ~/src/mongodb-linux-x86_64-1.8.1.tgz ./mongodb
以上でインストール自体は完了です。なまら簡単だべ?

データストアの置き場所を用意する

MongoDBでは、デーモンプログラム"mongod"の起動オプション"--dbpath"で、データストアのパスを設定できます。
今回は、$HOME/src/mongodb/data/db をデータストアにします。
~ $ mkdir ~/src/mongodb/data/db -p
これだけです。

mongodを起こす

ではmongodを起こします。
~ $ ~/src/mongodb/bin/mongod --dbpath ~/src/mongodb/data/db
フォアグラウンドで起き上がってきて、ログをだくだく吐き出したら、無事に起動できています。止めるときはCtrl+Cすれば止まります。

mongod起こした状態でweb管理インターフェースを見てみる

mongodを起こすと、ログの中に
Thu Apr 14 11:14:40 [websvr] web admin interface listening on port 28017
のような記述が見受けられます。見ての通り、「Web管理インターフェースがポート28017で待ち受けている」ということです。試しにブラウザでVPSの28017番ポートにアクセスしてみると、以下のようなページを見ることが出来ます。
セキュリティ的にはこんなのを外部から見れるようにしておきたくないので、mongod起動時のオプション"--nohttpinterface"を付加して、この機能を止めておきましょう。
あとはdaemontools経由で起こすなりしてやれば良いというわけですね。

2011-04-13

[Perl]Plack::Middleware::*を作ってみる

いい加減Plackが当たり前のこの頃ですが、いまだにPlack::Middleware::*を作ったことが無かったので、練習してみました。
なお、あまり気にせずに書いていたら、内容がほとんどPlack::Middlewareのドキュメントと似たものになってしまいました。

基本型

以下が、だいたい定型となるコードです。
package Plack::Middleware::OreOre;
use strict;
use warnings;
use parent qw/ Plack::Middleware /;

### enableでオプションを受け取る時に使用
# use Plack::Util::Accessor qw/ oreore watewate soregashisoregashi /;

our $VERSION = '0.01';

sub call {
    my ( $self, $env ) = @_;

    ### ここに処理をかく ###

    $self->app->( $env );
}

1;
__END__
Plack::Middleware::*を作るには、Plack::Middlewareを継承する必要があります。
で、callというメソッドですが、ここに実際の処理を書いてあげて、最後に$self->app->( $env )としてappを実行するようにします。もしHTTPレスポンスを返したい場合は、途中でPlack::Response形式のarrayrefをreturnしてあげればOKです。
もしenableするときにオプション値を取りたい(enable "OreOre", foo => 'bar'; とか)場合は、Plack::Util::Accessorを使う必要があります。
多分、これだけあれば大抵の機能をPlackに組み込むことができそうです。

ごく単純な例

ある特定パスにアクセスされた時に、他のページにリダイレクトする、というだけの単純なPlack::Middleware::Hogehogeをつくってみました。
package Plack::Middleware::Hogehoge;
use strict;
use warnings;
use parent qw/ Plack::Middleware /;
use Plack::Util::Accessor qw/ jump_url listen_path /;
our $VERSION = '0.01';

sub call {
    my ( $self, $env ) = @_;
    return [ 301, [ 'Location', $self->jump_url ], [''] ] if $env->{ PATH_INFO } eq $self->listen_path;
    $self->app->( $env );
}

1;
__END__
この場合、実際に使うときは以下の様なpsgiになります。
use Plack::Builder;

my $app = sub { [ 200, [ 'Content-Type', 'text/html' ], ['<h1>hoge!</h1>'] ] };

builder {
    enable "Hogehoge", listen_path => '/yahoo', jump_url => 'http://www.yahoo.co.jp/';
    $app;
};
これをplackupすると、/yahooにアクセスしたときだけYahoo!Japanにリダイレクトされ、それ以外は"hoge!"とかかれたページが表示されます。

ようやく少しはPlackの使い方に慣れてきました!

2011-04-07

[Perl]WebService::Simpleでレスポンスが文字化けしたら

XML::Simpleのパフォーマンスの話

WebService::Simpleは内部的にXML::Simpleを使っている。古い話だけど、XML::Simpleといえばこちらにもあるように「遅い」と評されることがあって、それはここに原因と対策がまとめられていて、掻い摘んで説明すると

・XML::SimpleはデフォルトでXML::SAX::PurePerlを内部的にパーサとして使用している。
・XML::SAX::PurePerl*が*遅いのであって、XML::Parserを使えば速度が改善される。

ということになる。そのためには
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
という具合に、XML::Simpleが内部的に使用するパーサにXML::Parserを指定すれば良い。

本題

のっけから脱線したけど、これはWebService::Simpleのparse_response()の結果が文字化けを起こすという現象にも、同様の事が言える模様。

use WebService::Simple;

my $ws = WebService::Simple->new(
    base_url => 'http://example.com/api',
    param => { api_key => '***' },
);

my $res = $ws->get( 'hoge/fuga', { q => 'piyo' } );
my $xml = $res->parse_response;

例えば、こんな具合で生成されたWebService::Simpleのオブジェクトがあって、parse_responseの戻り値が文字化けしていたとする。そんな時はまず、

use WebService::Simple;
use WebService::Simple::Parser::XML::Simple;

$XML::Simple::PREFERRED_PARSER = 'XML::Parser';

my $ws = WebService::Simple->new(
    base_url => 'http://example.com/api',
    param => { api_key => '***' },
    response_parser => WebService::Simple::Parser::XML::Simple->new( xs => $xs ),
);

my $res = $ws->get( 'hoge/fuga', { q => 'piyo' } );
my $xml = $res->parse_response;
この様な具合でresponse_parserを食わせてみると、文字化けが治ったりするかもしれない。