
レーキを踏む最も簡単な方法は、非同期を使用することです。 私は、文字通りマルチスレッドに屈した強力な専門家としての地位を確立したプログラマーに精通しています。 手始めに、デッドロックについての私のお気に入りの物語をお話しします(おかしなことを謝罪しますが、それはあまりにも良いです)
AP通信は約10年前、パイロットがどのようにしてスウェーデンのクリシャンスタッド市の空港に旅客機を着陸させようとしたかを世界に語ったが、彼の要求に応えたディスパッチャーはいなかった。 ディスパッチャはまだ休暇から戻っていませんでした。 その結果、飛行機は空港を一周し、緊急ディスパッチャが緊急に呼び出されました。
30分で飛行機を着陸させました。 デブリーフィングは、その理由が航空機の遅延であることを示しました。 休暇中の仕事に急いでいたまさにディスパッチャであった船上。
そのため、非同期性に直面したとき、頭の中の通常のイメージを壊さなければなりません。私たちの周りの主観的な世界はシングルスレッドです。 手紙を送り、1週間後に回答を受け取った場合、すべてが同じフロー内で発生します。 回答者と郵便配達員の行動に責任を負う必要はありません。 そして、私たちのコードに-それは必要です。
プログラマーの生活を簡素化するために、
Reactorパターンを使用できます。 Rubyの(私の意見では)最高の実装は
EventMachineです。 しかし、彼女との明らかな瞬間はありません。 そのうちの1つについて簡単に説明する予定です。
イベントマシン
gem install eventmachine
EventMachine
クラス
EventMachine
多かれ少なかれ
文書化されており、単純なクエリの処理は簡単です。 通常、すべては何らかの形で次のように発生します(
EM
は
EventMachine
エイリアスです):
begin EM.run do …
リアクターのシャットダウン時にフックを掛けることができます(
EventMachine.add_shutdown_hook {puts "Exiting ..."} )。 もちろん、その場で
非同期接続を作成できます。 繰り返しますが、ドキュメンテーションです。 場所でも、わかりやすい。
しかし、十分な退屈さ。
結果の収集
すべてが「要求→応答処理」モデルに限定されている限り、問題はありません。 しかし、前のリクエストの結果に応じて次のリクエストを送信する必要がある場合はどうでしょうか? メモを長くしすぎず、非常に単純な瞬間を噛まないために、すぐにタスクに進みます。
発見によってgubbirサーバー上で必要なコンポーネントを見つけ、それと通信します
つまり、これは何らかの形で次のように発生します。検出にリクエストを送信し、コンポーネントのリストを取得し、各コンポーネントの機能をインタビューします。 機能リストにあるものがある場合は、初期化します。
EventMachine
を使用すると、次のようになります(
EM
との作業に直接関係のないものはすべて削除しました)。
@stream.write_with_handler(disco) do |result| …
イテレータとそのマジック
マップ関数がすべての作業を行います。 最後の括弧内のラムダコード(コメント "yielding")は、見つかった各コンポーネントのすべてのdiscoinfoが収集されたときにのみ実行されます。
これが誰かに明らかであるように思われる場合、私は謝罪しますが、Googleは私に迅速な解決策を提供しませんでした。