言語設計のお勉強この広告は、90日以上更新していないブログに表示しています。operation"する時のデバッグ方法haskellのmutexであるMVarがデッドロックを起こしたときのデバッグ方法を解説する。必要がないならばasyncやstmなどの高度な表現を用いることが推奨される。8.0.1問題haskellにおける非同期処理では、データをやり取りする方法がいくつかある。そのうちのもっともプリミティブなものにMVarがある。MVarには一つだけデータが入る。データが入っている間は入る操作を他の箇所から行うことが出来ずスレッドはブロックする。データが存在しない間は読み出す操作を他の箇所から行うことは出来ずスレッドはブロックする。Intを経由して数字1をスレッドから受け取っている。このコードが以下のようだった場合デッドロックが起こる。operation"がstdoutに出力されてプログラムは終了する。対策この時、GHCのruntimeはBlockedIndefinitelyOnMVarという非同期例外を投げている。よってこの例外を主眼において操作を行うことでデバッグ情報を取得することが出来る。ghciでスタックトレースを行うことである。僕はghciでスタックトレースを取る方法を推奨する。https://downloads.haskell.org/~ghc/6.12.1/docs/html/users_guide/ghci-debugger.html#ghci-debugger-exceptionsターミナルでの操作を以下のように行う。*Main>ghciをoption-fbrea-n-exceptionつきで起動する。コマンドでmainを走らせるSomeExceptionが投げられプログラムが中断する:backコマンドでスタックトレースが行われるスタックトレースによってどの変数でBlockedしたのか、それがどのファイル名、どの行数で起こったのかなどがわかる。GitHubこれは行数、ファイル名が得られないため望ましくない。対応することもあるが、実行時の行数が得られないため、無意味である。mgemgithub.com設計上起こり得ないエラーを処理する例外クラスのmgemを公開した。これは、主に作業中のmgemにおいて使われることを想定している。分岐や変更の多い処理で一時的に例外をなげて、実装に考慮漏れがあることを明示するために用いる。テストを走らせたときなどに便利だと思う。endendこのクラスのオブジェクトを対応するC言語の構造体に変換したいとする。Data::Nameのような特定のデータを示すクラスとStringクラスのどちらも引数に取れたりする。*に変換したい場合それぞれで処理が異なる。オブジェクトの型チェックなどの判定処理を入れることになると思う。して、求められるC言語での実体をそれぞれの変数から取得して構築する。rubyの構造体の方に入る値はかなり柔軟に変更されることが予想できる。Fixnumも受け取れた方がいいだとかである。このような変更により処理に不整合が起こることが予想できる部分に書く例外としてImplementationErrorをmruby-implerrとして用意した。NotImplementedErrorは未実装な場合に投げる例外だと思うし、すべてをRuntimeErrorで処理するのは良くないと思ったためだる。ImplementationErrorはオプショナル引数を2つもち、数字と文字列を受け取れる。ImplementationError.new(__LINE__,__FILE__)のようにして、使うことを考えている。引数の順序はどちらを先にしても問題ない。C言語から例外を投げるImplementationErrorはC言語から投げられることが多いと思っている。ruby側ではちゃんとrubyとしてStandardErrorを継承したそれ用の例外をガンガン変更していける。処理を中止する用途で用いることを推奨する。僕が読んだことや関連したdraftをつらつらと記述していきます。動機と機能、そしてGoogle内部における導入事例の紹介を行うものです。後半はGoogleにおける運用状況の報告になります。Googleは、数年前から標準化に先んじて前進となるプロトコルを実装していました。QUIC(以下QUIC)と呼びます。Google内部間やモバイル/ウェブのChrome、YoutubeとGoogle検索とGoogle間における通信は可能な限りでGQUICで行われています。その通信を見ることが出来ます。Googleが行った数々の計測と実験の結果を公開しています。地域ごとの性能サーバのCPU使用率さまざまな条件における到達可能性の評価.などです。GoogleはHTTPサーバを独自に実装していますが、それらもproto-quicの実装と同じものを用いています。UDP関係QUICはUDP上に実装されているため、UDPの事情に強く影響を受けます。forgetであることですが、その他にも多くあります。PMTUUDPは経路MTUを考慮した通信を行う仕様を含みません。フラグメンテーション対策を行う必要があります。Discoveryを自らで行います。7.1に掲載されています。TCPに比べていくらかのCPU使用率の増加が見込まれます。これはQUICの内部状態TLSによる常時暗号化ストリーム並列化が主な原因であるとされています。1,2について記述します。QUICの内部表現QUICは一つのUDPのエンドポイントを複数のコネクションで共有して用います。ひとつのコネクションを複数のストリームで共有して用います。そのため、他のプロトコルスタックに比べてより複雑な内部状態を持つことになります。改善されたとしました。考慮すべき点は多くあり、性能の向上の余地は未だあるとしています。TLSによる常時暗号化QUICはTLS1.3の多くの機能を暗号化や認証のために用いています。ヘッダーは認証され、ペイロードは暗号化されます。このコストは相応に高くつくため、CPU負荷となっています。Googleは独自に最適化したChaCha20を用いることで負荷の軽減としました。良い性能が出ないケースQUICは常に他より良い結果が得られるわけではありません。その事例についての記述も存在します。endpointモバイル端末QUICは高RTT,低帯域幅、高い損失の対策として様々な情報を付加しています。そのため、それらが起こらない場合は情報を更かした分だけ転送効率が下がることがあります。TCPより性能が低下することがあります。効率の良いデータ転送を実現したとしても、処理しきれないことがあります。ネットワークスタックの改善の余地が少ないこともありえます。Monadの中でControl.Monad.Fail.failを実行すると、runGetOrFailのときにLeftを取ることが出来る。Monadの失敗をユーザがハンドルできる。MonadFailモナドの中での失敗を意味する型クラス。Monadのメソッドだったところを「分離していいよね?」という提案の元、型クラスに分離された経緯がある。packageのData.Binary.Getを正常に失敗させる方法を知りたい。失敗するかもしれないGetモナドを実行することができる。これをユーザがハンドルする方法がドキュメントに書いてなかった。モナドの失敗を扱うことが出来る型クラスであるためこれを用いたときに、失敗時の処理となるのではないかと思った。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。