history

青木日記 RSS

<前の日 | この月 | 次の日>

2007-03-08

fcgi.rb (5)

前回の書きかたはちょっと誤解を招くなあ。

いま問題にしている fcgi.rb のマルチスレッド化というのは、 単にライブラリのコードをマルチスレッドセーフにするという話ではない。 アプリケーションに、複数の FastCGI リクエストを並列に処理させる話である。 まあ、その結果として並列にレスポンスを送り返す必要が出てくるので、 結局マルチスレッドセーフにもしないといけないんだけども。

で、俺が一番困ってるのは実装ではなく、 並列発行をオンオフするインターフェイスである。 もし前例があるんならそれの真似して済まそうと思ったんだけども、 それがないみたいなのでどうしようかなと。

でもまあ、ないんならないで勝手に都合のいいインターフェイスを 作っちまえばいいわけだから、それはそれで楽だ (それで実は前例があった、ということになると困るんだけど)。 いまんところ Hash 引数を使おっかなーという気分になっている。 こうね。

FCGI.each_request(multithreads: true) do |req|
   ....
end

この場合、FCGI_MAX_CONNS と FCGI_MAX_REQS は適当なデフォルト値になる。 パラメータを細かく制御したいときは同様に

FCGI.each_request(multithreads: true, max_connections: 10,max_requests: 50) do |req|
   ....
end

とする。MPXS はデフォルトで true なので必要ない。と思う。

(07:19)

すごれんすまにゅある / 返り値の記述 (1)

リファレンスマニュアルでの返り値の記述について真面目に考える。

返り値について、何を書くべきだろうか。

  • 意味
  • 型?

……うん、まあ、こんなもんでしょう。 型は意味じゃないのかと問われると困るが。

では、どのように記述するか。 基本的に、意味は日本語で説明しなければならない。 で、それをどこに書くかだ。

  1. 普通に段落で書く
  2. @return を用意する

うーん。俺としては、あんま @return 使いたくないんだよな。 既存のドキュメントを見るかぎり、 @return を導入してもあんまりうまく文章を分けられそうにない。

例えば String#index のように返り値が重要なメソッドの場合 (function 的なメソッドと呼んでおく)、 第一段落 (メソッドの要約) に書くべきだろう。 「パターン pattern を文字列から検索し、そのインデックスを返す。 パターンが見付からなかったら nil を返す」 で十分に返り値の説明になっていると思う。

また Array#each のように返り値なんてどーでもいいメソッドの場合 (procedure 的なメソッドと呼んでおく)、 そんなもんはどーでもいいので引数の説明のあとにでも 「self を返します」と一言書いておけば十分だろう。

それに対して引数の説明はけっこう繁雑であるし、 引数と違って複数ありうるので、 @param を導入する意味はあると考える。 例えば String#index の第一引数 pattern について 条件を詳しく説明したほうがよいだろう。

ということで、俺としては @return は導入せず、 引数の意味が重要なときだけ第一段落に書く、 というのがよいのではないかと思う。

(20:10)

すごれんすまにゅある / 返り値の記述 (2)

返り値の型を書くべきだろうか。 また、書くとすればどう書くべきだろうか。

うーん。どうなんですかねえ。書く場合のデメリットを挙げると、

  • 同じことが (きっと) 文章に書いてある
  • 既存のドキュメントには書いてない (ので手間がかかる)

うう、なんかすでにこの時点でヤバいような気がしてきた。 ML にはいちおう型の記述方法の提案を出してはみたけど、 やっぱやめよっかなあ。

(20:15)

すごれんすまにゅある / 返り値の記述 (3)

@param を導入した主な理由は、 チェックを自動化し、書き忘れを防ぐことである。 実はあんまり再利用については考慮していない。 したがって @return についても @param と同様の規準で考えてみよう。

@return を導入するとチェックが自動化できるか。 んー、まあ、できるよな。書いてあるかどうかはわかる。

しかし、@return がなかったら返り値について書き忘れるかというと、 それはどうなんだろう。 function 的なメソッドで返り値を面倒だからとか、 うっかりとかで書き忘れることってあるのだろうか。 procedure 的なメソッドで忘れることならありそうだけど。

うーん、そうか……。 procedure で書き忘れるのを防止するために @return を導入する、 というのは意味があるな。 でもって、書き忘れのないようにするために @return を導入するなら すべてのメソッドにつけることにしないとまずい。

付けたほうがいいという結論に傾いてまいりました。

(20:27)

本日のツッコミ(全7件) [ツッコミを入れる]
Siena. (2007-03-13 05:35)

procedure 的なメソッドだと、事実上未定義、ということもありますよね。
self を返すのか、最後に評価した式を返すのか、意識してないコードとか。
後付けで self を返すことにする、と決まったり。
というわけで、@return 未定義、も許容するの希望。

あと、どんな例外が上がる可能性があるのかがリファマに書いてなくて、不便に思うことがしばしば。
いろいろテストして大丈夫だろうと思ったコードで、後になってから思いもよらぬメソッドから思わぬ例外が発生して、あちこち対処しなくちゃならなくなったり。
すごれんすまにゅあるでも、例外の記述は変わりません?

青木 (2007-03-13 15:21)

このルールは標準添付ライブラリまでの範囲の話なので、返り値はすべて決まってる (決めてもらう) ものと考えてます。書いてなくても結局使う人がいるんだもん。
例外は @raise で書きます。

Siena. (2007-03-13 22:20)

なる。@return は、それはそれで納得です。
書いてなくても使うひと対策で、「未定義」として決定を先送りする、というのは無しということですね。

えと、@raise で書けるのは分かるのですが。
果たして、発生する可能性のある例外を漏れなく網羅するという方針なのかしら、ということでして。

青木 (2007-03-13 22:45)

もちろん、全部書くのが前提です。ただ、SystemCallError の下位クラスとかは現実的に無理なような気もしています。あと、ArgumentError とか TypeError も頻度が高すぎるのでたぶん省略することになるでしょうね。フツー起きる、ってことで。

Siena. (2007-03-14 23:30)

たびたびどうもです。ArgumentError や TypeError については御意。

正直なところ、コーディングの際に Errno::* が厄介に感じてます。
どのメソッドでどんなシステムコールを呼んでいて、どのシステムコールがどんなエラー番号を返す可能性があるのかを把握してないと例外安全なコードを書けないのは、低水準で大変ですよね。
思慮が足りない人なので、テストでカバーしきれなくて、思わぬところで思わぬ例外が上がってしまい。なかなかコードが安定したという安心感を得られず、何か潜んでいいないかと不安がつきまといます。
Ruby を変えて SystemCallError 以下を抽象化するなどは今回の本旨でないので、リファレンスマニュアルとしては、(完璧でなくても) できるだけ文書化されていて欲しいと思うのです。せめて依存するシステムコールの一覧くらいないと、man してとも言いにくいです。

青木 (2007-03-16 23:09)

書かないとは言ってません。「(OSごとに違う分まで) 全部書くことはできない」ってだけです。POSIXで決まってる分くらいはたぶん書けるでしょう。

Siena. (2007-03-17 23:33)

とても手間がかかり過ぎるので善処するけれどカバーしきれない、ということと誤解していました。失礼しました。実際、それも仕方ない作業量かもしれませんが、できる範囲ででも検討していただければとても心強く思います。
しつこくなってしまってごめんなさい。ここらで退場させていただきます。

名前
メールアドレス

<前の日 | この月 | 次の日>
2002|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10