受け手の準備が整ってから処理を進めたいときには、ポーリングを使えばいい。
アプリケーションで、Messageを受け取る必要がある。 そのときに、メッセージを受け取るタイミングをアプリケーション側でコントロールしたい。
アプリケーション側での準備が整ってからメッセージを受け取れるようにするには?
メッセージコンシューマーの存在目的はたったひとつ。メッセージを受け取ることだ。 ただ、新しいメッセージがあるってことを、コンシューマーはどうやって知るのだろう? いちばん簡単なのは、コンシューマーが定期的にチャネルをチェックして、メッセージが届いているかどうかを調べるという方法だ。 これをポーリングという。
そのアプリケーションでPolling Consumerを使う。 これは、メッセージを受信したいときに明示的に受信呼び出しをするというものだ。
このパターンはSynchronous Receiverと呼ばれることもある。今回Polling Consumerという名前を採用した理由は、 受信者がメッセージをポーリングしてはそれを処理し、そして次のメッセージをポーリングする、という流れを意識したからだ。
便宜上、メッセージングAPIは二種類の受信メソッドを用意していることが多い。 メッセージが存在しなかった場合の処理が違っていて、一方はメッセージが届くまで処理をブロックするけれどももう一方はただちに呼び出し元に制御を戻す。
Polling Consumerは、アプリケーションがメッセージを明示的にリクエストして受信するときに使うオブジェクト。 アプリケーション側でメッセージを処理する準備が整ったら、コンシューマーをポーリングし、 コンシューマーがメッセージングシステムからメッセージを取得してそれを戻す(次のシーケンス図を参照)。
ただし、コンシューマーがメッセージングシステムからメッセージを取得する方法は実装依存であり、必ずしもポーリングしているとは限らない。
Polling Consumerを使えば、メッセージを同時にどの程度処理するのかをアプリケーション側で制御できるようになる。アプリケーション側の能力に合わせて、ポーリングするスレッドの数を絞ればいい。 これで、アプリケーション側でメッセージをさばききれなくなる事態を回避できる。処理しきれないメッセージはキューに入り、後で処理することになる。
受信側のアプリケーションは、監視したいチャネルごとに少なくとも一本のスレッドを用意するのが一般的だ。 しかし、単一のスレッドに複数のチャネルを監視させることもある。めったにメッセージがやってこないチャネルを監視する場合などはそうするだろう。 単一のチャネルだけを監視するスレッドの場合は、メッセージが届くまでブロックするバージョンの受信メソッドを使う。 一方、複数のチャネルを監視するスレッドの場合は、メッセージがなければすぐに制御を戻すバージョンの受信メソッドを使う。
JMSの場合、メッセージコンシューマーはMessageConsumer?.receiveでメッセージを同期的に処理する。
MessageConsumer?には三種類の受信メソッドがある。
たとえば、コンシューマーを作ってメッセージを受信するコードは、次のようにシンプルなものになる。
Destination dest = // ターゲットの取得 Session session = // セッションの作成 MessageConsumer consumer = session.createConsumer(dest); Message message = consumer.receive();
.NETの場合は、コンシューマーはMessageQueue.Receiveを使ってメッセージを同期的に処理する。
MessageQueueクライアントにはいくつかの受信方法がある。最もシンプルなものが次の二つだ。
既存のキューからメッセージを取得するコードは極めてシンプルだ。
MessageQueue queue = // キューの取得 Message message = queue.Receive();