メッセージキューを作成する

Q4M テーブルは単一のキューを表します。Q4Mテーブルの行は単一のメッセージを表します。メッセージキューを作成するには、エンジン名``queue''と一緒にCREATE TABLE ステートメントを使用します。
mysql> CREATE TABLE my_queue (v1 int not null, v2 varchar(255)) ENGINE=queue;
一つ以上の購読者にメッセージを発送する必要がある場合は、それぞれにテーブルを作成します。好きなだけQ4Mのテーブルを作成することができます。

メッセージの送信

メッセージを送信するには、対象のSQLテーブルに順番にINSERT ステートメントを使用します。
mysql> INSERT INTO my_queue (v1, v2) VALUES (3, "hello world!");

メッセージキューの購読

キューの購読は queue_wait 関数によって制御されます。
mysql> SELECT queue_wait('my_queue');
+------------------------+
| queue_wait('my_queue') |
+------------------------+
+                      1 |
+------------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM my_queue;
+----+--------------+
| v1 | v2           |
+----+--------------+
|  3 | hello world! | 
+----+--------------+
1 row in set (0.00 sec)
queue_wait 関数の後で、関数によって指定されたテーブルに対する連続するSELECTクエリによって最大1つの行だけが返るでしょう (queue_wait への呼び出しと他の他の条件をまぜないで下さい)。キューテーブルに利用可能なデータが無い場合は、関数は何らかのデータが利用可能になるかタイムアウトが起こるまで関数をロックするでしょう。関数が呼ばれるたびに(ある場合には)新しい行が返され、以前に返された行が自動的に削除されます。特定の数の行を処理した後で、プロセスを終了したい場合は、最後に呼ばれた queue_wait() 関数で返された行を削除するqueue_end()を呼ばなければなりません。
mysql> SELECT queue_end();
技術的には、Q4Mはメッセージキューを表すために二つのモードを使用します。NON-OWNER モードでは、Q4Mテーブルは通常のテーブルと同じ操作をします。OWNER モードでは、接続によって所有された 行だけが見えるようになります。これらの機能はview間の切り替えと、メッセージが利用可能になるまでのブロックのために使われます。
queue_wait 関数を呼ぶことで、Q4MテーブルはOWNERモードに入ります。OWNERモードに入ると、接続から排他的に(最大で)一つの行のみが SELECT テーブルになります。つまり、接続に所有される行が他の接続から見えなくなります。Q4M テーブルが空になると、queue_wait 関数は行が見えるようになるまでブロックするでしょう。関数がタイムアウトすると、SELECTクエリによって見えなくなるでしょう。
行を処理すると、クライアントは queue_end 関数または queue_wait 関数のどちらかを呼ばなければなりません。接続に所有される行は自動的にテーブルから削除されます。queue_end 関数を呼ぶことで、テーブルは NON-OWNER モードに戻ります。queue_wait 関数を呼ぶことで、処理されるべき新しい行が見えるようになるでしょう。クライアントが行を扱うのに失敗すると、他のクライアントによって処理ができるように テーブルに owned-row を返す queue_abort 関数を呼ばなければなりません。
以下の Perl コードはキュー関数を使用するもっと改まった方法です。
while (1) {
  # wait until any data becomes avialable (or timeouts)
  $dbh->do('select queue_wait("test_table")')
    or die $dbh->errstr;
  # receive data (only one row becomes ready at once)
  if (my @row = $dbh->selectrow_array('select * from test_table')) {
    # handle the row
    unless (process_row(@row)) {
      # if failed, return the row to queue
      $dbh->do('select queue_abort()')
        or die $dbh->errstr;
    }
  }
}
# tidy up
$dbh->do('select queue_end()')
  or die $dbh->errstr;

Prioritized Subscription

バージョン 0.3 では、queue_wait関数にテーブルのリストを渡すことで一度に複数のテーブルを購買することが可能です。データが利用可能になると、queue_wait 関数はテーブルのインデックスを返すでしょう。テーブルは左から右に優先度を付けられ、もし一つ以上のテーブルがメッセージを含む場合は最も左のテーブルのインデックスが返されるでしょう。テーブルに利用可能なデータが無い場合は、0が返されます。関数の呼び出しのこの形式において、同様にタイムアウトが指定されるべきです。例では10秒のタイムアウトで二つのテーブルを購買します。
mysql> SELECT queue_wait('high_priority_table', 'low_priority_table', 10);

条件付きサブスクリプション

バージョン 0.4 では、特定の条件に合う行だけを購買することが可能です。例えば、以下のqueue_wait の呼び出しは、v<3となる行が利用可能になるか、タイムアウトが起きた場合にのみ返ります。
mysql> select queue_wait('table:v<3');
以下の操作が現在のところサポートされています。現在のところ、整数の列および定数がサポートされています。浮動小数点あるいは文字変数はまだサポートされていません。
- ~ ()
^
* div % mod
+ -
<< >>
&
|
= != <= < >= >
not
&& and
xor
|| or

メッセージのリレー

バージョン 0.3 では、Q4Mは異なるMySQLの間でのメッセージのリレーをサポートします。つまり、Q4Mテーブルにサブミットされたメッセージは異なるサーバで動作している他のQ4Mテーブルに転送することができます。転送は信頼できるものです; メッセージの損失 および/または 複製 を避けるために、rowidが使われます。
単純なリレーを実行するには、MySQLインストレーションのbinサブディレクトリにインストールされている q4m-forward スクリプトを使ってください。
% /usr/local/mysql51/bin/q4m-forward \
  "dbi:mysql:database=db1;table=tbl1;user=foo;password=XXX" \
  "dbi:mysql:database=db2;table=tbl2;host=bar;user=foo"
メッセージブロッカー(フォーマットあるいはメッセージの宛先を変更するリレー)を実装することも可能です。もっと詳しい情報は、q4m-forward スクリプトのソースコードを参照してください。
TOP
inserted by FC2 system