I/Oに制限された操作があると仮定します。コールバック(またはem-synchrony)があります
- EMは、前のリクエストをコールバックを待機させたまま、次のリクエストを処理するようにどのように切り替えますか?
- Thread.current変数をどのように分離しておくのですか?
- 長時間実行されるジョブをエミュレートするにはどうすればよいですか?
I/Oに制限された操作があると仮定します。コールバック(またはem-synchrony)があります
1. EMは、前のリクエストをコールバックを待機させたまま、次のリクエストを処理するようにどのように切り替えますか?
どのreactorパターンでも、実行のスレッドは1つです。つまり、一度に実行できるのは1つだけです。リアクタがそのメインスレッドでリクエストを処理している場合、他のリクエストは介入できません(協調スケジューリング)。これで、リクエストは、自発的に(EMでは)制御を「放棄」するかEM.next_tick { # block }
、将来の操作をスケジュールすることによって(タイマー(EM.add_timer { #block }
))、または別のIO操作を行うことによって制御を「放棄」できます。
たとえば、EM-Synchronyを使用している場合、HTTPリクエストを(em-http経由で)行うと、リクエストがディスパッチされると、ファイバーが一時停止され、内部でコールバックが作成されます。リクエストが終了すると、コールバックは内部コールバックを介してEventMachineによって呼び出され、コントロールはリクエストに戻ります。詳細については、 http ://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/をご覧ください。
2. Thread.current変数をどのように分離しますか?
魔法はありません。Rubyには、スレッドローカル変数がありますThread.current[:foo] = bar
。同様に、ファイバーのセマンティクスは同じですが、人々を不意を突かれることがあるのは、同じメカニズムが使用されていることですThread.current[:foo] = bar
。
ここを参照してください:http://devblog.avdi.org/2012/02/02/ruby-thread-locals-are-also-fiber-local/
3.長時間実行されるジョブをエミュレートするにはどうすればよいですか?
最善のアプローチ:それらを原子炉の外に移動します。これはどのリアクターシステムにも当てはまります。
a)ジョブキューを作成し、それを別のプロセスにプッシュします。b)EMはEM.defer
、別のスレッドを生成するを提供します。
(b)よりも可能な限り(a)を選択してください。後で感謝します。