飽きっぽい人のブログ

プログラマとしてもテスターとしても中途半端な人のブログ

C# for Systems Programming Part2 fail fast

C# for Systems Programmingの情報がJoe duffy氏のブログで新しいのが書かれていたので和訳してみます。例によってGoogle翻訳を使っての拙い訳です。

-----------------------------ここから和訳-----------------------------

If you’re going to fail, do it fast

私たちの言語開発チームで検討した技術の一つは"fail-fast"と呼ばれるもので、プログラムが可能な限り迅速にバグが検出された後に失敗するというアイデアだ。このアイデアは本当にフィクションなどではなく、現実的なアプリケーションなものだ。多分ね。

下記のものは私たちが開発中のシステムでfail-fastとなるものである。

・契約違反(Contract violation)

・実行時宣言違反(Runtime assertion violation)

・Null参照先のデータ取得(Null dereference)

・メモリ不足(Out of memory)

・スタックオーバーフロー(Stack overflow)

・ゼロ除算(Divide by zero)

・算術オーバーフロー(Arithmetic overflow)

もしあなたが.NETで投げられた例外の内の90%を見て、それらが上記の状況によるものである。これは面白い。

これは例で、開発中のシステムに似たものだ:

これは最終的に以下のようになる。

私の経験では開発者はふつう、以下の二つの失敗状態の反応により、一つを行うことで終了する。

1.キャッチして続行する。一般的にはバグを隠ぺいし、それが難しく後で検出するために行う。

2.プロセスをクラッシュさせる。その後スタックは戻されて実行が終了する。潜在的に重要なデバッグ状態は失われる。

私は合法的キャッチして例外を処理する3番目があると仮定したが、それは珍しいものでリストに上げたくはない。それらは通常プログラミングのエラーであり、キャッチされるべきでまた容易だ。"キャッチして無視"の規律は莫大な壊れたウィンドウとなる。

例外はその場所を持っている。しかし、入出力、データ、の残り10%のシナリオについては再スタート可能だ。(例:パーサなど)

私たちが既存のコードベースにfail-fastを適用したときには案の定多くのバグを見つけることができた。これは例外ベースの事故にはふくまれていないが、常に返値ベースのものだ。私たちが移植したのは音声サーバのプログラムだった。それは数年前からHRESULTが内包されていたルーチンで実装されていたが誰も気づいてなかった。悲しいことにこれが台湾の顧客は80%のエラーに見舞われた。fail-fastはそのエラーを私たちに対面させた。

このカテゴリに算術オーバーフロー(Arithmetic overflow)をいれることにあなたは疑問を抱くだろう。その通りで、私たちはデフォルトで計算チェックを使用している。興味深いことに、これは私たちが遭遇した障害のなかで共通して最もストレスの元となったものだった。(おかげで大部分がfail-fastとなるだけでなく、競合状態やデッドロックを排除して、安全な実行モデルとなる。・・・しかし私は脱線する)。なんて腹立たしいことだと言うかもしれない?まさか! ほとんどの時間は開発者が実際のところオーバーフローが可能であるなんて期待していなかったし、無言のラップアラウンドは偽の結果をもたらすだろう。事実、共通のセキュリティ開発の元は今日、整数オーバーフローをトリガーすることにより得られる。最善は開発者にそれをスローして対面させること、そして、その開発者にチェックをはずすかどうか決めさせることだ。

メモリ不足(Out of memory)は別のケースだから横に置いておこう。現代のアーキテクチャは障害をさける方法をとるよりかは、むしろ、障害を容認する傾向がある(例:再スタートできること、状態を書き込めることなどなど)。そう、オブジェクト指向モデリング硬化が時間とともにどんどん珍しくなる傾向になっている。それゆえ、fail-fastのデフォルトは実際ほとんどのコードにおいて正しいものだ。しかし、いくつかのサービスに--カーネル自身のような--は不適切なのかもしれない。私たちがどのようにこれに取り組んだかはブログ投稿を見てほしい。

.NETは既にfail-fastを選択的に使用している。このように"corrupted state exceptions”

私たちは積極的により広く、C#と.NETへのfail-fastの規律を適用し、調査している。だから、期待してほしい。しかしながら、幅広いプラットフォームのサポートがない場合にはその規律があなたのコードベースで簡単に採用できるのだ。

-----------------------------ここまで和訳-----------------------------

方針としてはやって当たり前なチェック処理は既定でやるようにして、必要に応じてそのチェックを外せるようにするみたいですね。このあたりがC++とは違うのでしょうか。 まあ、算術オーバーフローの項のuncheckedはC#にすでにあったと思いますが。

例にでてたrequires構文?はD言語のin契約に似ている印象(D言語まともにやったことないけど)。というかこれC#にも欲しい機能です簡潔に引数チェックできそうですし。

気になっていたメモリ管理についてはノータッチだったのでこの言語の評価はまだ何とも言えないですね。少し前の記事でクラス実装終わったみたいなこと書いてたんでぼちぼち情報が出てくるんじゃないでしょうか。とりあえずお蔵入りになってなくてよかったです。