I have a function that does quite a bit of intensive processing. Once in awhile I need to be able to stop it (i.e. for DB maintenance) even if it's mid-run. I'd like to send it a SIGINT so it can wind up what it's doing gracefully. What I found was as soon as I introduce a normal perl interrupt handler, the function stops responding to interrupts properly.
Working
CREATE OR REPLACE FUNCTION run_for_awhile() RETURNS void
AS $_X$
spi_exec_query('select pg_sleep(30)');
$_X$
LANGUAGE plperlu;
If I do select run_for_awhile()
in psql, I can type Ctrl+C
and it cancels. In the actual app I'd be doing select pg_cancel_backend(PID)
but my tests have the same outcome via that method.
If I modify the function to capture SIGINT and/or SIGTERM, the signal gets sent, but the function doesn't notice it until after 30 seconds (when pg_sleep finishes). So the handler does run eventually but not "immediately".
i.e.
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;