Net::Server その2(長い処理をしたい)
前回(http://d.hatena.ne.jp/dayflower/20060908/1157706291)の続きです。やろうと思っていることは,
といったクラサバです。前回までに 1. と 2. の一部をやりました(コマンドを与えるというより接続しただけですが)。で,今日やりたいのは 3. のあたりの一部です。
時間がかかる処理ということで sleep をかましてみます。前回の process_request のとこで,
sub process_request {
my ($self) = @_;
warn 'accepted';
eval {
my ($in, $out, $err);
IPC::Run::run(
[qw( /bin/date )],
\$in, \$out, \$err,
IPC::Run::timeout(10)
)
or die $?;
print STDOUT $out, "\n";
};
croak $@ if $@;
sleep 5;
warn 'bye bye';
}
croak 〜 warn の間に sleep をいれる。するとクライアントから接続すると 5 秒後に日付を出して終了します(当たり前)。そうではなくて,クライアントから接続してすぐに終了して欲しいのです。
では,ソケットを close するとクライアントはすぐに終了してくれるのか。
...(略)... close *STDIN; close *STDOUT; sleep 5; warn 'bye bye'; }
と変えて接続してみましたが,駄目(日付がでて5秒後に接続が切れる)。fork して子プロセスに分離してみたりしましたがやはり駄目でした。
Net::Server の sub post_process_request をみてみると,STDIN 等を close した後に $self->{server}->{client} なるハンドルを close しています。こちらがソケット本体でしたか。
このハンドルをじかに触るのもなんなので,考え方を変えて,
sub process_request {
前回と同じ
}
sub post_process_request {
my $self = shift;
$self->SUPER::post_process_request;
sleep 5;
warn 'bye bye';
}
post_process_request をオーバーライドして解決してみました。
すると見事に client から接続するとすぐにコネクションが切れ,5 秒後にサーバログに「bye bye」と出力されました。
本当はこのままでは駄目なのです。Net::Server の run_client_connection を見るとわかりますが,allow_deny によって deny だった場合にも最後に post_process_request に至るのでよろしくないのです。でもこれでとりあえず道筋は立ちました,ということで。
(ここまで書いておきながら,fork して子プロセスの先頭で $self->post_process_request を呼び,最後に exit を呼ぶほうが本筋な気がしてきました)