NAME
Fugu::Signal - signal handlers for graceful shutdown
SYNOPSIS
use Fugu::Signal;
my $sig = Fugu::Signal->new;
$sig->setup_interrupt_flag('INT', 'TERM');
until ($sig->interrupted) {
do_some_work();
}
DESCRIPTION
Fugu::Signal installs signal handlers so that a signal can interrupt a program safely. The program does not leave temporary files, child processes or half-written state behind.
setup_interrupt_flag() only sets a flag. The program must do a check of the flag and stop where a stop is safe.
The object keeps the previous handlers. restore() puts them back, and the destructor calls restore(). Thus a scoped object leaves the process in its initial state.
Each manager owns its handlers and its interrupt flag. Two managers in one process do not see each other's state. The installed handlers close over the object, so a handler always finds the manager that installed it.
new
new() creates a signal handler manager. It does not install handlers.
setup_interrupt_flag
setup_interrupt_flag(@signals) installs a handler for each named signal. The handler sets the interrupt flag and returns. No other action occurs until the program reads the flag.
restore
restore() puts back the handlers that this object replaced.
interrupted
interrupted() reports if this manager saw a handled signal.
reset_interrupted
reset_interrupted() clears the interrupt flag of this manager.
check_interrupted
check_interrupted() reports if any live manager saw a handled signal. It is a plain function, not a method. It serves code that runs far from the object, for example a poll loop deep in a library. Code that holds the object uses interrupted().
RETURN VALUES
new() returns a signal handler manager. setup_interrupt_flag(), reset_interrupted() and restore() return the object. Thus the calls can chain.
interrupted() and check_interrupted() return true if a handled signal came.
EXAMPLES
This example stops between items and not in the middle of one:
my $sig = Fugu::Signal->new;
$sig->setup_interrupt_flag('INT', 'TERM');
for my $item (@items) {
last if $sig->interrupted;
process($item);
}
ERRORS
No method dies.
SEE ALSO
perlipc(1), kill(2), sigaction(2), Fugu::Process
AUTHORS
Dick Olsson <hi@senzilla.io>
CAVEATS
check_interrupted() answers for the whole process. It returns true when any live manager saw a signal, and it cannot tell the caller which one.
The handlers are standard Perl signal handlers and run between opcodes, not immediately. A program that a system call blocks sees the signal when the call returns.