2009年4月アーカイブ

大量のメルマガなどを配信する場合、サーバのスペックによってMTAにキューを投げる
間隔(時間)を調整したり、他サーバをリレーさせたりするのが一般的。

ただこれらをブラウザから行なうと、いつまでもブラウザが開放されず、timeoutに
なってしまう。
なのでこういった場合は、時間のかかる処理をバックグラウンドにまわして、ブラウザは
さっさと開放する。
(「まぐ●ぐ!」などで、即時配信した後、すぐ管理画面に戻れるのはそういった
仕掛けがあるからです。)

perlでバックグラウンド実行を行なうには、fork()関数か、ithreadを使う場合が多い
らしい。

速さから言えばithreadのほうが速いらしいが、ithreadは必要なモジュールが標準でセットされてないので、お手軽なのはfork()。←現在は標準になってる模様

-------------------------------------------------------------------
#!/usr/bin/perl -w

$| = 1; #バッファ制御

sub start_imme{ #### 即時配信処理

######## ここらでパラメータ受け取り

########## ここらでメールデータをセット

########### ここらでMIMEフォーマットなど

########## ここらで配信する読者をセット

my @user_no = "配信するユーザ番号など";

if(@user_no == 0){
&error("配信可能な読者がいませんでした。");
}
######## ここからバックグラウンド処理開始
else{
FORKLABEL: { ##ラベル開始
if( $pid = fork ) { # 子プロセス生成。$pidにはforkのプロセスNoが返る
###### ここは親プロセスのみで実行
&show_imme_done(); ###「配信完了」などの表示をここで出力
###### 標準出力を閉じてブラウザ開放
close(STDOUT);
wait;  ###### 子プロセスを待たないと子がゾンビになります
}elsif (defined $pid) {
###### ここは子プロセスのみで実行

###### 標準出力を閉じてブラウザ開放
close(STDOUT);

###### ここらから時間のかかる処理

######### メール送信
my $mass = 10; # 一斉送信数
my $interval = 5; # 待ち時間
my $i = 0;
my $bench = time;
while($i < @user_no){
&sendmail(
$mail_to,
$mail_from,
$reply_add,
$envelope_add,
$sbj,
$body
);
if($i){
if($i % $mass == 0){
sleep $interval;
}
}
$i++;
}
my $req_time = time - $bench;

########## この辺で配信履歴の保存処理など

}elsif ( $! =~ /No more process/) {
# 生成するプロセスが多すぎる時は、少し待って再チャレンジ。
sleep 10;
redo FORKLABEL;
}else {
##### ここにくるようなら、perl自体動かないはず。

die "forkがサポートされていません。サーバ管理者にお問い合わせください。";
}
} # ラベルの閉じ
}
exit;
}
最近yumのパッケージなどあまり更新してなかったので、久々にやるかと思って、
GUIでアップデートを行なったらいきなりperlスクリプトが500Internal Server Error。

うざーー!

最初にCGI::Carp qw(fatalsToBrowser)を呼んでいるので、このエラーの場合は
たいていヘッダー出力が間違っていることがほとんど。

しかしどこもおかしくない。

/var/log/httpd/error_log を見ても、お得意の
「Premature end of script headers」

しかしよーく見ると
「Can't locate object method "splitpath" via package "File::Spec" at /usr/lib/perl5/5.10.0/CGI/Carp.pm line 361, line 64.」

なので、試しに、同じようにCarp.pmを使用してるMTのスクリプトにアクセスしてみたら、同様のエラーコメント。


今回のyumアップデート直後のエラーだけに
/var/log/yum.log を見てみる。

Apr 25 16:01:29 Updated: httpd-2.2.11-2.fc10.i386
Apr 25 16:01:29 Updated: 4:perl-libs-5.10.0-68.fc10.i386
  ・
  ・
Apr 25 16:02:37 Updated: cpan2rpm-2.028-6.fc10.noarch

うーん、なんかこの辺が怪しい感じ。


アパッチのアップデートも入ってるけど、perlのモジュールを結構全面的に
書き換えてる感じだから、とりあえずエラーが出てるおおもとの
File::Specモジュールをとりあえずインストールしなおすかってことで・・

たしかこれはCpanのRPMパッケージだったはずだから、とりあえず、

----------------------------------------------------
# rpm -e perl-File-Spec

# rpm -q perl-File-Spec
パッケージ perl-File-Spec はインストールされていません。

----------------------------------------------------


と、ここで何となくスクリプトを実行してみたら、
あれ・・・動いた・・・。

MTにもちゃんとログインできる・・・


/usr/lib/perl5/ の中を確認すると、何か知らんけどFile::Specモジュールが
入ってる・・・
ということは、今回のアップデートでperl5.10.0の標準モジュールになった
ってこと?
いやいやそんなはずはない。Carp.pmなんてずっと昔から使ってるんだから。

rpmを削除してスクリプトがちゃんと動くってことは、今まで標準
モジュールよりRPMパッケージの方を優先して読み込んでたってこと?

てゆうか、最初からFile::Spec入ってるのになんで俺RPMでインストールしちゃって
るんだろう?

とにかく今回のモジュールアップデートでどこかダブったんだか改行コードがおかしく
なったんだかようわからんが、直ってよかった。

2日ハマったのでメモ。

このアーカイブについて

このページには、2009年4月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2009年2月です。

次のアーカイブは2009年5月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

Powered by Movable Type 4.22-ja