無料スクリプト配布のPHP.TO   PHPの実用的なtips PHPマニュアル MySQLマニュアル Apacheマニュアル PostgreSQLマニュアル マニュアル検索    

31.8. 非同期通知

PostgreSQL は、 LISTEN NOTIFY コマンドを使用した、非同期通知をサポートします。 クライアントセッションは、 LISTEN コマンドを使用して処理対象とする特定の通知チャネルを登録します。 (通知監視を取り止めるには UNLISTEN コマンドを使用します。) 任意のセッションでそのチャネル名による NOTIFY コマンドが実行されると、特定チャネルを監視しているすべてのセッションは非同期に通知を受け取ります。 監視者に追加データを通信するために "ペイロード" 文字列を渡すことができます。

libpq アプリケーションは、通常のSQLによる問い合わせと同じように LISTEN UNLISTEN および NOTIFY コマンドを発行することができます。 NOTIFY メッセージの到着は、続いて PQnotifies を呼び出せば検出できます。

PQnotifies 関数は、サーバから受信した通知メッセージの未処理リストから次の通知を返します。 保留中の通知がなくなればヌルポインタを返します。 PQnotifies が通知を返すと、その通知は処理済みとみなされ、通知リストから取り除かれます。

PGnotify *PQnotifies(PGconn *conn);

typedef struct pgNotify
{
    char *relname;              /* 通知チャネル名 */
    int  be_pid;                /* 通知元サーバプロセスのプロセスID */
    char *extra;                /* 通知ペイロード文字列 */
} PGnotify;

PQnotifies で返された PGnotify オブジェクトの処理が終わったら、 PQfreemem を使用して確実に解放してください。 PGnotify ポインタを解放することは重要です。 relname extra フィールドは別の割り当てを表していません。 (これらのフィールド名は歴史的なものです。特にチャネル名はリレーション名と関係するものである必要はありません。)

例31-2 で非同期通知を使用したサンプルプログラムを示しています。

PQnotifies() は実際にサーバのデータを読み出すわけではありません。 これは単に、他の libpq 関数が吸収してしまっていた通知メッセージを返すだけです。 libpq の以前のリリースでは、通知メッセージを適切な時点で確実に受け取るには、空の問い合わせでも何でも、とにかく一定時間ごとに問い合わせを送り、そして PQexec() を実行するたびに PQnotifies() を検査するしかありませんでした。 今でもこの方法は動作しますが、処理能力の無駄使いをすることになるのでやめておくべきでしょう。

実行すべき問い合わせがない時に通知メッセージを検査するよい方法は、まず PQconsumeInput() を呼び出し、それから PQnotifies() を検査することです。 サーバからのデータの到着を select() で待つことができ、不必要な動作で CPU パワーを消費してしまうことがありません。 ( select() で使用するファイル記述子番号の取得については、 PQsocket() を参照してください。) なお、これは問い合わせに PQsendQuery PQgetResult を使った時でも、またはおなじみの PQexec を使った時でも動作します。 しかし通知がコマンドの処理中に届いていないかどうか、 PQgetResult あるいは PQexec の実行ごとに PQnotifies() を調べることを忘れないようにしておくべきです。


powered by SEO.CUG.NET