#author("2018-04-15T17:05:50+00:00","default:haikikyou","haikikyou")
[[PostgreSQL/開発]]
#contents
* 概要 [#e195b03b]
- SIGALRMによる割り込みを多重化するためのライブラリである。
- 長時間クエリのタイムアウトを監視するStatementCancelHandlerなどの、PostgreSQL本来の機能に加え、ユーザー独自のタイムアウトを設定することも可能である。
&label(warn){参考};[[(utils/timeout.h) enum TimeoutId>https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/include/utils/timeout.h;h=5a2efc0dd94fc5daed3844408577f12b9ffa4f15;hb=ad4fb805ad08c86dd6389e6755081dfd7c864416#l23]] - &size(11){&color(gray){https://git.postgresql.org/gitweb/?p=postgresql.git;a=shortlog;h=refs/heads/REL_10_STABLE};};
#ref(./timeout-overview.png,100%)
- 複数のタイマーの管理は、アクティブなタイムアウトの存在と、最も近いタイムアウト時間に合わせてタイマーを設定することで実現している。
- タイムアウト情報は、all_timeoutという配列で管理されている。登録可能なタイマー数には制限がある。PostgreSQL10.0のソースを確認すると16(0~15)となっており、8個(0~7)が予約済みであるため、実質8個(8~15)のタイマーを登録可能である。
- 有効化されたタイムアウト設定は、active_timeoutsという配列に登録される。この配列は、all_timeouts要素の参照を保持する配列である。この配列で管理されるタイムアウト設定は、最もタイムアウト時間が直近のものから昇順に整列されている。つまり、active_timeouts[0]の要素が、最も直近に発火すべきタイマーとなっている。よって、timeoutライブラリは、タイマーの設定においてactive_timeouts[0]のfin_timeを呼べばよく、タイマー設定処理がシンプルになっている。
- タイマーが発火すると、MyLatchのフラグがセットされるため、MyLatchで待ち状態となっている処理は復帰する。また、indicatorというフラグがタイムアウト情報にセットされる。このフラグを見て(&code(){get_timeout_indicator};)、登録したタイマーが発火したか否かを判断できる。
- タイマーの発火で登録していたタイムアウト設定のハンドラーが呼ばれると、そのタイムアウト設定はactive_timeouts配列から削除される。従って、再びタイマースケジュールしたい場合は、enable_timeout_after関数などを呼びアクティブにする必要がある。
* 定義 [#z90736c7]
** 変数,エイリアス [#c2fa847d]
** マクロ [#ffb64d59]
** 列挙型 [#bd396b49]
** 構造体/共用体 [#t10c1dfa]
*** Struct [#k2ab7574]
|~番号|~データ型|~フィールド|~説明|h
** 関数 [#v6487eee]
*** 関数名 [#v629683a]
#geshi(c){{
// 引数1:
extern ForeignServer *GetForeignServer(Oid serverid);
}}
- 説明
* サンプルプログラム [#yb927eb0]
以下は、timeout.hの各種関数を拡張機能から呼び出すサンプルである。~
詳細は、添付の&ref(./my_timeout.zip);を参照。
#geshi(c){{
/*-------------------------------------------------------------------------
*
* timeout_test.c
* Timeout test code
*
* IDENTIFICATION
* contrib/timeout_test/pg_retire.c
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "fmgr.h"
#include "utils/timeout.h"
PG_MODULE_MAGIC;
static TimeoutId MyTimeoutId = USER_TIMEOUT;
static void my_timeout_handler(void);
static void my_timeout_handler(void)
{
ereport(DEBUG3,
(errmsg("MyTimer fired!")));
}
PG_FUNCTION_INFO_V1(my_register_timeout);
Datum
my_register_timeout(PG_FUNCTION_ARGS)
{
if (MyTimeoutId != USER_TIMEOUT)
{
ereport(WARNING,
(errmsg("timeout is already set.")));
PG_RETURN_INT32(-1);
}
MyTimeoutId = RegisterTimeout(USER_TIMEOUT, my_timeout_handler);
PG_RETURN_INT32(MyTimeoutId);
}
PG_FUNCTION_INFO_V1(my_enable_timeout_after);
Datum
my_enable_timeout_after(PG_FUNCTION_ARGS)
{
int timeout_after = PG_GETARG_INT32(0);
enable_timeout_after(MyTimeoutId, timeout_after);
PG_RETURN_BOOL(true);
}
PG_FUNCTION_INFO_V1(my_enable_timeout_at);
Datum
my_enable_timeout_at(PG_FUNCTION_ARGS)
{
int timeout_at = PG_GETARG_INT32(0);
enable_timeout_at(MyTimeoutId, timeout_at);
PG_RETURN_BOOL(true);
}
PG_FUNCTION_INFO_V1(my_disable_timeout);
Datum
my_disable_timeout(PG_FUNCTION_ARGS)
{
disable_timeout(MyTimeoutId, true);
PG_RETURN_BOOL(true);
}
PG_FUNCTION_INFO_V1(my_get_timeout_indicator);
Datum
my_get_timeout_indicator(PG_FUNCTION_ARGS)
{
bool indicator;
indicator = get_timeout_indicator(MyTimeoutId, false);
PG_RETURN_BOOL(indicator);
}
PG_FUNCTION_INFO_V1(my_get_timeout_start_time);
Datum
my_get_timeout_start_time(PG_FUNCTION_ARGS)
{
int64 start_time;
start_time = get_timeout_start_time(MyTimeoutId);
PG_RETURN_INT64(start_time);
}
PG_FUNCTION_INFO_V1(my_get_timeout_finish_time);
Datum
my_get_timeout_finish_time(PG_FUNCTION_ARGS)
{
int64 finish_time;
finish_time = get_timeout_finish_time(MyTimeoutId);
PG_RETURN_INT64(finish_time);
}
}}
* 参考・関連 [#tdfd2e8b]
- [[utils/misc/timeout.c>https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/misc/timeout.c;h=d7fc040ad31da8669a2e237a9787f51942955dee;hb=ad4fb805ad08c86dd6389e6755081dfd7c864416]] - &size(11){&color(gray){https://git.postgresql.org/gitweb/?p=postgresql.git;a=shortlog;h=refs/heads/REL_10_STABLE};};
- [[Timeout test code - my_timeout>https://github.com/moritoru81/pg_misc/tree/master/my_timeout]] - &size(11){&color(gray){on https://github.com/moritoru81/pg_misc/};};
&label(rel){関連};
#related
* コメント [#l62c167b]
#comment