2017-09-25 10 views
1

かなり処理が集中している機能があります。しばらくしてから、中断していても(DBメンテナンスのために)停止する必要があります。私はそれが正常に何をしているかを巻き込むことができるようにSIGINTを送っていきたいと思います。私が見つけたのは、通常のperl割り込みハンドラを導入するとすぐに、関数は割り込みに正しく応答しなくなりました。私はpsqlでselect run_for_awhile()を行う場合どのように割り込み(つまりSIGTERMまたはSIGINT)を処理するのですか

CREATE OR REPLACE FUNCTION run_for_awhile() RETURNS void 
    AS $_X$ 
     spi_exec_query('select pg_sleep(30)'); 
$_X$ 
LANGUAGE plperlu; 

作業

、私はCtrl+Cを入力することができ、それがキャンセルされます。実際のアプリでは私はselect pg_cancel_backend(PID)しているだろうが、私のテストはその方​​法で同じ結果を持っています。

SIGINTおよび/またはSIGTERMをキャプチャするように関数を変更した場合、シグナルは送信されますが、関数は30秒後(pg_sleepが終了するまで)通知しません。したがって、ハンドラは最終的には実行されますが、「すぐには」実行されません。あなたがここに行う必要がありますどのような

CREATE OR REPLACE FUNCTION run_for_awhile() RETURNS void 
    AS $_X$ 
     $SIG{INT} = sub { die "Caught a sigint $!" }; 

     spi_exec_query('select pg_sleep(30)'); 
$_X$ 
LANGUAGE plperlu; 
+0

こんにちは、おそらくhttp://dba.stackexchange.comの人があなたをより速く助けることができますか? –

答えて

2

すなわち

は、あなたのPerlがCHECK_FOR_INTERRUPTS()マクロがないのと同じCコードを呼び出す割り込みハンドラ持っている、それは次のようになります。

if (InterruptPending) 
     ProcessInterrupts(); 

(もしあればあなたがもう少し必要なウィンドウで、src/include/miscadmin.hを参照してください)。

残念ながら、あなたは簡単に呼び出せるラッパー関数はありません.plperlはにCHECK_FOR_INTERRUPTSを呼び出すようです。

変数が設定されていると、アプリケーションのメインループをSELECT 1にするPerl割り込みハンドラでグローバルを設定するオプションがあるようです。少し醜いですが、うまくいくはずです。

そうでない場合は、おそらくPerlのInline::Cなどを使用してProcessInterruptsを呼び出すことができます。

plerlがCHECK_FOR_INTERRUPTS()のPerlラッパーを公開しているといいですね。パッチを提出することを検討してください。

+0

ありがとうクレイグ、私は合理的な代替を見つけたので、私はそれを深くするつもりはない...しかし、これはまさに私が探していた答えの種類です! – Ryley

0

私はこれの底まで完全に到達することはできませんでしたが、周りに道がありました。 SIGINTとSIGTERMは利用できないので、使用しないでください。しかし、SIGPROFのように、別の割り込みをうまく送ることができます。送信されたら、SIGINTをフォローアップして、すべてが期待どおりになる。

CREATE OR REPLACE FUNCTION run_for_awhile() RETURNS void 
    AS $_X$ 
     $SIG{PROF} = sub { die "Caught a sigprof $!" }; 

     spi_exec_query('select pg_sleep(30)'); 
$_X$ 
LANGUAGE plperlu; 
関連する問題