Prioritized Subscription 時の Q4M の動作
複数のキューの中で、データのあるものを探して取って来る Q4M の便利機能。
mysql> SELECT queue_wait('high_priority_table', 'low_priority_table', 10);
これのこと。
エラーキューとしてウチでは使おうと思っているが、これの動きに若干癖があったのでメモっとく。
まず、この書き方をするときは、タイムアウト指定が必須。
select queue_wait('a', 'b');
こういう書き方をすると、a テーブルの中身しか見てくれない。
select queue_wait('a', 'b', 60);
のようにタイムアウトを必ず指定する。(上の例だと60秒)
ちなみに、これはチュートリアルにも書いてある。
若干??になったのが、
チュートリアルの一番上に書いてある「一番簡単なq4mの使い方」の例 SQL
mysql> SELECT * FROM my_queue WHERE queue_wait('my_queue');
を、Prioritized Subscription の場合どう書けばいいのか?ということ。
結論としては、「この書き方は出来なくなる」のではないかと思った。
奥さんの説明によると、Prioritized Subscription の時は、
select queue_wait('a', 'b', 60);
とやってもらって、a にデータがあれば、1、b にデータがあれば、2 が
返って来るんで、それで取り出すキューを決めてくださいと。
で、その際にもし、データを取ってないキューを見ても問題ない。
例えば、a にも b にもデータが入っていた場合、a からは一件のデータが取得できるが、そのときにもし、b を見たとしても Empty set が返って来るだけですよ、ということだ。
これは実際試してみてもそうだった。
なので、奥さんが想定しているやり方というのは、
select queue_wait('a', 'b', 60);
⇒1が返って来た場合:
select * from a;
⇒2が返って来た場合:
select * from b;
という風に queue_wait() の返却値で from を分ける方法なのだと思う。
ただ、ちょっと思ったのは、奥さんの説明によるとデータの無いキューに対して select をかけても Empty set が返ることは保証されてるそうなんで、
mysql> select * from a union select * from b;
というのもありだなーと。若干無駄な負荷が発生してしまうが、上記のようにすると、どっちかデータのあったほうを返してくれる。うちではプログラマーさんが上記の場合わけコーディングを面倒臭がったんで、こっちのやり方になりそうだw。
追記:
select queue_wait('a', 'b', 60);
において、実際に無いテーブル等を指定すると、NULL が返って来る。これも後から気付いたので、メモっておく。いわゆる実行時例外系ではあるが、呼び出し側は NULL を想定しとく必要はあるだろう。