非同期接続
前頁では同期接続関数を試してみたが,libpqには接続要求を投げてすぐに返ってくる非同期接続関数がある.これを試してみた.
本頁では,PostgreSQLに非同期接続する方法について記述する.この方法では,サーバの応答が遅い場合などにノンブロッキングな接続要求関数を呼び出しておいて,別の処理を行なうことができる.そして後から接続状態をチェックし,準備ができていればサーバに要求を行なう.おおまかな流れを以下に示す.
- 非同期接続要求(ノンブロッキング)
- 接続要求結果のチェック
- サーバ接続状態に依存しない任意の処理
- サーバ接続状態のチェック
- サーバ接続状態に依存する処理
- 切断
PostgreSQLに非同期接続要求を行なうサンプルを作成した.
このサンプルは,非同期接続要求を行ない,それから接続状態を確認して切断するだけのサンプルである.ではコンパイル.
gcc -I/usr/include/postgresql/ -lpq connect_nowait.cそして実行
$> ./a.out "host=dbserver user=matsu password=hogefuga dbname=firstdb" conninfo : host=dbserver user=matsu password=hogefuga dbname=firstdb CONNECTION_MADE PGRES_POLLING_READING fd = 3 PGRES_POLLING_READING fd = 3 PGRES_POLLING_READING fd = 3 PGRES_POLLING_READING fd = 3 PGRES_POLLING_OKサンプルをいじっていくつかの場所にsleepをばらまいて試したところ,PQconnectPoll(connection)は最低4回呼ばないとPGRES_POLLING_OKにならないように見えた.
非同期接続関数は以下である.
PGconn *PQconnectStart(const char *conninfo)引数はPQconnectdbと同じである.返り値もPQconnectdbと同様,PGconnの領域確保失敗しなければNULL以外が返る.ただし,PQstatus関数の返り値の取り得る値が異なる.
- CONNECTION_STARTED
- 接続確立待ち
- CONNECTION_MADE
- 接続OK.送信待ち
- CONNECTION_AWAITING_RESPONSE
- 接続OK.応答待ち
- CONNECTION_AUTH_OK
- 認証済み.バックエンド起動待ち
- CONNECTION_SETENV
- 環境設定中
PQconnectStartがCONNECTION_BADでなければ,裏で接続処理が進んでいるので,その間にサーバ接続状態に依存しない任意の処理を行なうことができる.今回のサンプルではこれは行なっていない.で,それらが済んで,サーバ接続状態に依存する処理を行なう前には,接続状態が正常かどうかをチェックする必要がある.これには以下の関数を使用する.
PostgresPollingStatusType PQconnectPoll(PGconn *conn)この関数の返り値に応じて,さらにサーバ接続状態に依存しない処理をしながら待ったり,タイムアウト指定しつつ接続を待ったりする.以下に一覧を示す.
- PGRES_POLLING_ACTIVE
- 接続アクティブ.
- PGRES_POLLING_READING
- 読み込み中.以下の関数で接続ソケットのファイルディスクリプタを取得して,selectやpollができる.
int PQsocket(const PGconn *conn)
-1が返ったときは,サーバとまだ接続できていない.サンプルではselectした.もちろん再びサーバ接続状態に依存しない処理を行なうこともできる. - PGRES_POLLING_WRITING
- 書き込み中.読み込み中の場合と同様,selectやpollができる.
- PGRES_POLLING_OK
- 接続アクティブ.サーバに要求できる状態.
- PGRES_POLLING_FAILED
- 接続失敗.PQfinishしてから接続を再要求する必要がある.また,PQerrorMessageでサーバからのエラーメッセージを取得できる.

