昨日は病院に行って、その後仕事の打ち合わせをして、へとへとになって戻ってきたわけですが。戻ってみるとメールボックスにりすと亭で致命的な問題が起きているというメールが……。
ともかく直す必要があることが分かったので、今日は朝からそれに掛かりっきりでした。面倒な作業になると予測していましたが、手間は予想以上でした。
問題の焦点は、SMTPサーバが容量制限を行っている状態で、それを超える電子メールを配送させようとしたとき、何が起こるか、どう対処させるかです。
まず最初に再現テストをしようと思いました。しかし、それが最初の関門でした。通常使っているSMTPサーバは容量制限を掛けていません。それに制限を掛けると仕事のメールを拒否してしまう可能性も否定できないし、設定を間違えれば、重要なメールが届かない可能性もあり得ます。そのため、既存のメールサーバはいじれません。
では、どうするのか。
テストマシンのWindows 2000 ProfessionalのIISを使おう。とちょっと冴えたアイデアを思い付きました。これのSMTP機能なら、どう設定をいじっても、業務とは関係ありません。最初は、HDDの容量をごっそりファイルで奪って、残り容量が少ない状態を人工的に創り出してエラーを起こさせようと思っていましたが、最初から容量制限が設定されていることが分かって、その手間は不用でした。
さて、アイデアは冴えていましたが、いざやろうとしてびっくり。
IISが入っていない……。そういえば、これをインストールした頃はバリバリのApacheユーザーで、IISはインストールしない主義だったような気もします。
しょうがないので、IISを追加させました。途中でWindows 2000のCD-ROMを要求されて、焦りました。机の上にそれはあって、なんとなく場所を記憶していたので助かりました。しかし、こんなことが今度もあるだろうと思って、CD-ROMの内容をサーバ上にコピーしておくことにしました。サーバ上にあれば、CD-ROMの山と格闘するよりも素早く見つけられるので。そのコピー時間も取られて時間を食いました。
更に、このWindows 2000はSP3までしか当たっていなかったので、SP4も当てることに。これがまた時間が掛かりますね。SP4を当てたら、更にそれ以後のアップデートもWindows Updateで入れねばなりません。またまた時間を食ってしまいました。
さて、次の問題はテストに使う電子メールアドレスです。動作テストを始めるとすぐに迷惑メールが数通飛んでくるような状況ではスムーズに作業が進まないので、テスト用の電子メールアドレスの変更も行いました。これはでは、神崎ひとみさんという架空のアドレスを使っていましたが、これは廃止。今度は南楓さんと日高安純さんという架空のアドレスを作成しました。こんなことをしていると、またまた時間を食われます。
やっと再現環境もできて、動かしてみると、バッチリ問題の症状が再現できました。
そこで、ソースを見ながら、じっと考えます。対処方法は、前から考えていた、問題を起こすメールは事前チェックリストに送り込む、という処理で良いと思いました。しかし、それを実際に実現するコードはどうあるべきか。
りすと亭のSMTP送信はマルチスレッドで実現されていて、複数のSMTPサーバに同時並行で送信できます。(これが、かなり人数の多いメーリングリストでもスムーズに扱える理由と言えます)。もし、1つのSMTPサーバへの送信が失敗しても、他のSMTPサーバを使って再試行するようになっています。しかし、全てのSMTPサーバへの送信失敗した場合は特別な処理が必要です。その場合、これまではCommunicateExceptionという例外を投げていました。これは通信プロトコルで何らかのエラーになった場合に投げられるものです。これを継承して、「全てのSMTPサーバへの送信失敗した場合」にあたるFatalMultiSmtpSendExceptionという新しい例外を作成しました。この例外が起こった場合は、対象のメールを事前チェックリストに送り込めば良いわけです。
それに対応して、事前チェックリストの通知メールには理由を付加するように変更しました。管理者による設定で通知される場合と、通信エラーで通知される場合があることになるので、どちらか分かるようにするためです。
さて、実際にそのようなコードを組んで動かしてみると、通知メールが管理者に届きません。おかしいな、と首をひねって調べていると、とんでもないことに気付きました。
通知メールは、対象となるメールを全て含んだ形で送信されます。しかし、それを容量制限に引っかかるメールでやれば、通知メール自身も容量制限に引っかかって送信できません。それでは意味がありません。
仕方がないので、通知メールを送信する際、エラーが起きた場合は最初のテキストパートだけを再送するように更にコードを追加しました。最初のテキストパートは、どのようなメールに対して何が起きているのかを説明する文章と、事前チェックリストのURLが書き込まれています。これさえ届けば、最低限のことは分かるはずです。
と言うわけで、苦難の末に、やっと動くようになりました。
その他に、「返信しないメールアドレスにMAIL-DELIVERYを追加」という修正項目がありますが、これは必要が認識されていた修正をついでにやってしまったものです。りすと亭では、postmasterなど、SMTPサーバーのエラーメールの送信元となる名前は全て特別なものとして処理しています。その名前に、これも追加したと言うことです。これにより、この名前のメールアドレス(MAIL-DELIVERY@piedey.co.jpなど)から来た電子メールは、リスト板管理者に転送されることになります。
というわけで、やっと以上の作業が終わりました。
一段落して一息です。
りすと亭も、まだまだやることが多数あります。