更新通知メール実験

やはり LaCoocansendmail がおかしい。

01: require 'net/http'
02: 1.upto(10) do |num|
03:   fork do
04:     start = Time.now
05:     print sprintf("%02d: ", num)
06:     print Net::HTTP.get('asagi.la.coocan.jp', "/***.rb?num=#{num}")
07:     puts sprintf("[%f]", Time.now - start)
08:   end
09: end
10: Process.waitall
11: puts 'done.'
07: ok. [0.173849][0.382810]
05: ok. [3.401589][3.598008]
01: ok. [3.411678][3.622182]
02: ok. [3.296500][3.741416]
08: ok. [0.148340][5.259441]
09: ok. [30.058917][30.255057]
03: ok. [30.044667][30.275023]
04: ok. [30.052900][30.274581]
06: ok. [30.058942][30.257860]
10: ok. [30.045731][30.488688]
done.

このスクリプトは Net::HTTP で更新通知メール送信処理を外部から起動する実験用 CGI を fork で多重に呼び出しそれぞれ実行時間を計測する。

06 行目の "/***.rb?num=#{num}" は実験用 CGI のパス。パラメータ num はメール本文に転記され、05 行目と 07 行目で出力する実行時間と不達メールの対応を確認できるようにした。出力結果の「ok.」から左の [] は実験用 CGI に出力させた、sendmail にパイプを開いて本文を流し込む根幹処理の実行時間だ。
ちなみにこっちがその根幹処理。こんだけ。

    def send
      open("| #{MTA} -t", 'w') do |f|
        f.puts @from
        f.puts @to
        f.puts @bcc if @bcc
        f.puts @subject
        f.puts
        f.puts @msg
      end
    end

結果として上記例では 09, 03, 04, 06, 10 のメールが不達である。通常 1〜4 秒程度で終了するところを 30 秒でタイムアウト(?)した場合にメールが配信されないようだ。これが大体平均 2 割程度の頻度で発生する。この他 15 秒タイムアウトで不達のケースも確認されている。


さて、回避策はあるのだろうか。
nifty に聞いても「障害報告はない*1」「サポート対象外*2」でオシマイだろうなあ。
うーむ。

*1:障害(の可能性)の報告に対してこの返答はどうかと思う。「調査します」くらい言っとけよ。

*2:使えると謳っている機能が使い物にならないという報告にこの逃げはズルい。