GServer can exceed the max connections

前回 Ruby の gserver のことについて書いた後、少しばかり調べを進めてみていたら、 Ruby 2.2 からは標準添付ではなくなるとの「事実」に遭遇してしまいました。いいライブラリだなと覚えた矢先でしたから、がっかりです。尤も、標準ではなくなるだけのことですから、使い続けることはできるでしょう。

ただ標準添付から外される理由に、(1)テストも無い代物で、(2)ドキュメントどおりには振る舞わず(後述)、(3)だれもメンテナンスしていない状態である、ということが挙げられていて、それがために誰も使っていないから外す、とのことでした。加えてその提案がなされたのが3年前ということもあって、じぶんとしてはまったくモチベーションが下がってしまいました。

Feature #5480: remove GServer from stdlib - ruby-trunk - Ruby Issue Tracking System

確かに、テストがありませんでした。卵が先か鶏が先か、ゆえにメンテナがいないのも頷けます。そして誰も使っていないかというと、それはどうでしょうか。じぶんにとって、それはどうでもいいことでしたから、特に調べもしませんでしたが、ちょっと検索をかけてみた所では、サンプル以上のことを書いている記事は見つけられませんでした。しかし Ruby で TCP サーバを書く人がどれだけあるかと想像すると、あまりいないんじゃないかという根拠のない──あるとすれば偏見から、思われるので、サーバを書く人がいないから、メンテされるほどの課題が出て来なかったのかも知れない。と、前向きに?考えることにして、動作に問題がないならば、標準であろうがなかろうが、だれが使っていようが、だれも使っていなかろうが、便利ならば使えばいいのだという結論に至ります。

そのコードは、 Perl ばかり書いて来たじぶんにとって馴染みの薄いスレッドを使っている所が特徴的なわりにすっきりしていてじつにシンプルです。みんなこれを使えばいいのにと、改めて思います。そうして使う人が増えれば、メンテナンスするひとも出てくることも期待できるでしょう。

じぶんはある実務で SMTP サーバを書く必要が生じて、 midi-smtp-server という gem を選択して使い始めたのが gserver を知る切っ掛けでもあったのですが、いまのところ上手くいっています。インターネットに出ない閉じたネットワーク内で使う代物なので、細かい気遣いをすることはなかったのですが、いざというときに内部動作が理解しやすいことも、ライブラリの選択にあたっては重視していましたから、その内容がシンプルであることは心理面でも助けになりました。

さて、そんな経緯もありながらしばらく gserver を扱っているのですが、自作の SMTP サーバのテストを書いている時に、最大コネクション数が設定値を超えてしまう現象に遭遇しました。それも再現性がなく、ときどきです。

冒頭の、標準添付から外される理由の(2)として挙げられているのは、このことかなと思いました。

ソースに当たってみると、最大コネクション数の管理とスレッドが連動しているところなど、なるほどこういうもんなんだなと鵜呑みにしてしまっていましたが、よくよく見ていると、クライアントの接続要求に応じて生成された子スレッドの中で現在の接続数を増やしているので、その処理が通るのが先か、または親スレッドが新たに接続要求に応じて現在の接続数をチェックするのが先かで、結果が違ってくるんじゃないかと思えて来ました。

そこで、ものは試しに、修正を加えてみることにしました。

hiroaki/gserver at tight-max-connection-limitation

rspec を追加したコミットを先にして、修正前のオリジナルを試験してみますと、じぶんの手元のマシンでは 100 回試行すればそのうち数回は設定した最大接続数を超えた接続が行われ、テストが失敗しました。そして、追加の修正コミットのあとは、試行回数 1,000 にしても、最大接続数を超えることはなくなり、テストは成功ました。うまくいったようです。これもライブラリの内部がシンプルな構造であったためにできたことかもしれません。(ここで、できた、というのは、手を入れてみようと思うことができた、というところにかかっています。)

ただし、パッチした影響で、ほかの機能の安全が守られているかどうかというのが判らないのが、不安の残る所です。こういうときに、テストがもともと無いのには、確かに困ります。現在のバージョンにテストがないということは、そのこと自体が将来の発展を妨げる一因となっていると、いえる事例かもしれません。

ところでこのブランチ、フォーク元にプル・リクエストを出してみようかとも考えましたが、少なくとも誰かにレビューしてもらってからのほうがいいかと思って躊躇っていました。でもメンテされていないものにマージしてほしいとは言えません。 gserver は標準添付ということで心強く思ってたのですが、これまで述べて来たようにもともと頼りないライブラリだったとあれば、このままお蔵入りにするか、プライベートで使うだけの代物になるだろうと思います。しばらくは実務で使ってる実装の方でも、オリジナルの動向の方でも、様子を見守るスタンス、です。

──見守るとは言いますが、 SMTP サーバを書くにあたって代わりになる、かつメンテナンスされているものがあれば、それを使って行きたいというのが本音ですけれども。みなさんは SMTP サーバを書く時に、どんなライブラリを使っているのでしょうか。