Mojolicious::Liteでforkする。

nginx+fcgiwrap+Mojolicious::Liteでforkして、親プロセスは終了させて子プロセスで処理を続行させていたのですが、どうも親プロセスが終了してくれないように見えたので色々試していました。
(FastCGIだからこうなのかもしれないし、morboとかhypnotoadだと変わってくるかもしれないです。)

Apache+CGIの時に使ってた処理

my $pid = fork();
die "fork fault: $!" unless defined $pid;
if($pid){
	# 親プロセス
}
else{
	close(STDOUT);
	close(STDIN);
	close(STDERR);
	# 子プロセス
}

今回の処理

use POSIX 'setsid';

my $pid = fork();
die "fork fault: $!" unless defined $pid;
if($pid){
	# 親プロセス
}
else{
	setsid;
	open (STDIN, "</dev/null");
	open (STDOUT, ">/dev/null");
	open (STDERR, ">&STDOUT");
	# 子プロセス
}

設定色々いじってスクリプトとか使えなくなることが多かったのですが、ようやく移行が終わったのでしばらくは放置でいいかなと思います。(→死亡フラグ)
めんどくさいので本番環境をぶっつけでいじりまくったのですが、ログ見てたらupicoとかlistとか処理途中なのに容赦なくサーバ止めまくってたので申し訳なかったです。(※あんまり反省してない)

Mojolicious::Liteのルーティング先がnginxで404になる。

nginx+fcgiwrap環境に移行した時にMojolicious::Liteアプリのルーティング先(http://hoge.com/fuga.pl/route)が404なのが解消できなくてはまりました。
confファイルでlocation ~ \.pl$を指定していたのですが、よく考えたら末尾が.plで終わらない限りperlのスクリプトとして処理されないので、location ~ \.pl($|/) で解消しました。
こんな間抜けな理由ではまるのどうにかしたいです。
もともと共用のレンタルサーバでCGIで動かしてたスクリプトをそのまま移行したのと、ちょっと色々あってmorboでもhypnotoadでもPSGIでもなくFastCGIで動かしています。
ほんとはhypnotoadで動かしたいんですが…。

追記(index.plで受ける場合)

        #中略
        location / {
                root /path_to_index/;
                if (!-f $request_filename) {
                        rewrite ^/$ /index.pl last;
                        rewrite ^(.*)$ /index.pl$1 last;
                }
        }

        location ~ ^(.+\.pl)(.*)$ {
                #中略
                fastcgi_index  index.pl;
                fastcgi_param  SCRIPT_FILENAME  /path_to_script/index.pl;
        }
        #中略

もっとスマートな方法があるんだろうなと思いつつ、これしか思いつかなかったので。

followingとfollowerをリストに突っ込むスクリプトのさらに続き。

forkでApacheのタイムアウト時間無視できるようにしてたつもりが、普通にkillされてたので処理を書き直しました。
あと、DTIのVPSで公開DNSサーバを踏み台にされてるユーザがいるそうで、それで周りのサーバもみんな不安定になってるみたいです。私はBIND系入れてないのですが、とりあえずチェックだけはしときました。
色々工夫したのですが、サーバへの負荷と処理の煩雑さを見るとコールバックで処理完了通知を書くのは無理なので諦めました。
一番楽な方法として「処理の完了通知をDMかツイートで行う」というのがあるのですが、ユーザの意思に反する投稿を行うのは私のポリシーに反するので、リストの説明文に処理結果を出力することにしました。
とりあえず5000人の配列で3600人くらいまで入れられたのでもういいかなって気がします。前にも書いたけど、15分スリープ処理とか、途中から再開する機能の実装はそこまでする義理がないのでやりません。メール通知版だけ15分後に再開させるようにしました。通知しない版は終了確認で負荷がかかるのと、むやみにプロセス増やしたくないので切り捨てました。
retrorocket/list

あと、今回色々あってgithubのリポジトリ全部消そうか悩むレベルで本当に懲りたのと、リアルでもご指摘受けたのでgithubのREADMEにライセンスについて書いておきました。BSDライセンスが自分の希望と組み合わせて使えるのかわからないのですが、とりあえず「list関数は流用したら著作権表示をお願いする」形式で行きたいと思います。無理そうなのでBSDライセンスだけにしました。
私がgithubにソースを載せているのは、ロジックに怪しい部分がないとかそういうことの証明に使ってるというのと、Twitter API周りはモジュールの使い方とかサンプルみたいなものがないと取っ掛かりが厳しいと思うので、ちょっとプログラム書いてみたいけどよくわからないと思ってる方向けに公開しています。自分が色々な方の書いたコードに助けられてる面が大きいので、自分も力になれればいいなーっていう気持ちです。まあモジュール叩いてるだけだから何もしてないっちゃしてないんですけど…。
プログラムすらすら書ける人からみたらひどいコードですが、このソースコード書くまでに私もそれなりに時間をかけて学習していて、そのままコピペされたのを使われてサービス公開されたらさすがに凹むので勘弁してください。

あと、人のコードを流用して使うときはロジックと環境をちゃんと理解してから使って欲しいなぁと思いますし、自分も人のコード使うときは理解して使いたいなと思います。

フォロワーを全員(5000人)リストに突っ込むスクリプトの続き。

処理に時間かかりすぎてタイムアウトしてる方が多い印象だったので、処理の終了をメールで知らせる機能を実装しました。(まだリリースはしてません。あとで差分のコード追記しておきます。)
色々迷走した結果、結局一番最初に実装したmojoliciousのmailプラグインでメールを送るだけ、という何の面白みもない仕様になりました。ちなみにfavicoのメールフォームもこれを使っています。

$self->mail(
        to      => 'postのパラメータで受け取ったアドレス',
        subject => 'タイトル',
        data    => '本文' ,
        from    => '差出人のメールアドレス'
);

ザクリ!グサリ!ドチャリ・・・町は一瞬にして血に染まり・・・

フォロワーを全員(5000人)リストに突っ込むスクリプト。

作った奴に頼んだら作ってくれるだろって発想が湧いてくるあたりほんとゆとってんなーすごいなーって思いました。(KONAMI

TimeLine Copier – フォローしてる人をリストにコピーするツール
retrorocket/list
まあつくったんだけど。

せっかくなので1年ぶりくらいにRubyをさわろうかと思います。CSV処理くらいしかやったことないけど。

あと、このブログのタイトルとかの元ネタになってるモンスーノが最終回を迎えてからもう3ヶ月ですね。
WP3.8の管理画面がめっちゃくちゃコアテックっていうかチェイスさんみたいな配色なのでなんだかしんみりしてしまいました。
モンスーノ終了で空いた心の穴を埋めるためにガイストクラッシャーを見ていますが、やっぱり物足りないですね。