切掛
偉い人「監査するからデータ収集スクリプトを使って全サーバ(数十台)のデータくれ」
1つのスクリプト自体は10分程度で終わるけど、全てにログインして手動でやるのは
流石に面倒なので、一括処理のために作ったperlスクリプトの超抜粋。
sequencial.pl
foreach(対象リスト){
処理色々;
}
※処理色々はsshやexpectでゴニョゴニョ
これで数時間放置したら自動で集められるようになった。
ある日
偉い人「データ収集スクリプトがバージョンアップされたからこっち使って」
性能劣化?なのかやることが増えたのか30~40分、長いと1時間超えになった。
単純計算でも24時間で終わらない。
仕方がないので並列処理化。
parallel.pl
$kids=0;
foreach(対象リスト){
$pid=fork;
if($pid){
$kids++;
next;
}else{
処理色々;
exit;
}
}
for(1..$kids){
$pid=wait();
print "$pid 終わり\n";
}
ここから本題
処理自体は無事完了したけど下記症状が発生。
- "$pid 終わり\n"が、本当に改行の動作しかしないことがある。(\rをつければ復帰もした)
- 終了してプロンプトに戻ったあとに、キーボードを受け付けなくなった。
そんなわけで調査開始
やったこと | 結果 |
---|---|
処理色々をローカルでの処理にする | ○ |
処理色々をsshのみにする | ○ |
処理色々をexpectのみにする | △(発生しないこともある) |
処理を変えずに対象リストの中身を1つにする | ○ |
expectらしいけど、発生しないこともあるのはなんで?ということでexpectを深掘り。
調査その2
やったこと | 結果 |
---|---|
expectを1つだけ実行させる | △ |
expectを複数実行させる | △ |
なんでexpectの数量とは関係ないってなんで?中身の問題?
調査その3
コード確認 | 結果 |
---|---|
expect eofがある | ○ |
expect eofがない | △ |
というわけで、expectのスクリプト作成時の問題。
標準出力の掴み合いでなにか起きているのかな?(治ったからこれ以上は掘らない)
シーケンシャルだと雑な作りでもキレイに動いちゃうんだね。
正規のものにしないからって、動きゃいいって割り切るとこういうことになるという残念事例。