ファイヤープロジェクト
非同期接続
2004-02-23T22:20+09:00   matsu
前頁では同期接続関数を試してみたが,libpqには接続要求を投げてすぐに返ってくる非同期接続関数がある.これを試してみた.
本頁では,PostgreSQLに非同期接続する方法について記述する.この方法では,サーバの応答が遅い場合などにノンブロッキングな接続要求関数を呼び出しておいて,別の処理を行なうことができる.そして後から接続状態をチェックし,準備ができていればサーバに要求を行なう.おおまかな流れを以下に示す.
  1. 非同期接続要求(ノンブロッキング)
  2. 接続要求結果のチェック
  3. サーバ接続状態に依存しない任意の処理
  4. サーバ接続状態のチェック
  5. サーバ接続状態に依存する処理
  6. 切断
接続要求結果のチェックは,同期接続要求の場合と同様の処理であるが,取り得る状態が異なる.非同期接続要求なので,裏でサーバ接続をしている間,プログラムはサーバ接続状態に依存しない任意の処理が行なえる.非同期接続要求なので,サーバ接続状態に依存する処理,具体的にはサーバにSQLを発行するなどの処理は,サーバ接続状態が正常であることを確認した上で行なう必要がある.サーバ接続状態が異常な場合は,接続要求からやり直す必要がある.
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
環境設定中
サンプルの実行結果ではCONNECTION_MADEになった.とにかくCONNECTION_BADでなければ次のステップに進む.
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でサーバからのエラーメッセージを取得できる.
matsu(C)
Since 2002
Mail to matsu