だるろぐ

だるいぶろぐです

例えば複数のpsgiをplackupするときにforkを使う

※この記事は自力ではありません


1つのアプリの中で複数の.psgiをplackupしたいときがある。
そんなとき、

  • 複数ターミナルを立ち上げてplackup
  • screenで複数ウィンドウ

などの手段で1個1個コマンド打ってもいい、のだけど、例えばforkでこんなことを。


今回は5000番と5001番を使う簡単なpsgiを例に取る。

psgi

# 5000.psgi

return sub {
    return [
        '200',
        [ 'Content-Type' => 'text/plain' ],
        [ "port: 5000" ],
    ];
};

# 5001.psgi

return sub {
    return [
        '200',
        [ 'Content-Type' => 'text/plain' ],
        [ "port: 5001" ],
    ];
};

打ちたいコマンド

% plackup 5000.psgi -p 5000 # デフォルトで5000番だけど例なので明示的に
% plackup 5001.psgi -p 5001


この2つのコマンドを1個のプログラムの中でforkして同時に動かす。

# main.pl

use strict;
use warnings;

my %children;

for my $arg (@ARGV) {
    if ($arg =~ /500\d/) {
        my $pid = fork;
        defined $pid or die "can not fork";

        if ($pid == 0) {
            exec "plackup $arg.psgi -p $arg";
            #die $!;
        }

        $children{$pid} = 1;
    }
}

#$SIG{TERM} = $SIG{INT} = $SIG{HUP} = sub {
#    kill 'TERM', keys %children;
#};

while (keys %children) {
    my $pid = wait;
    #delete $children{$pid};
}


見たまんまだけど一応流れ。

  1. 子プロセスを作って実行したいコマンドをexec
  2. 子プロセスのプロセスidを記憶
  3. 親プロセスが子プロセス全てをwait

あとは

% perl main.pl 5000 5001

で2つのコマンドを実行できる。終わったらc-cで全部止まる。



っていうのをボスがやってるのを見て真似している。
https://github.com/kazeburo/GrowthForecast/blob/master/growthforecast.pl
とかでも似たようなことをしている。

todo

上記のmain.plのコメントアウト部分はボスを真似したはいいものの、理解できない上にいじりまくってデバッグしていたら無くても動くことに気付いてでも書いたからには必要で意味があるはずなんだろうなと思いつつ結局放置しているのでいつか頑張る予定のまま永い月日が経っている。