Search code examples
perlcrontimeoutalarm

Perl alarm() or Time::Out Without Kernel SIG


I have a script which occasionally misbehaves while communicating with a web server. The server hangs or is very slow to respond with data.

I am currently using alarm() as a hack to get the script to terminate—so as to not flood the system with threads—but this causes a cron error, which alerts the sysadmin, who really doesn't want the 200 emails this produces when the system has fallen over.

Is there an alternative method of terminating a script (or apiQuery, if need be) that won't cause a non-OK exit and the corresponding email?


Solution

  • You can throw an exception in your signal handler, and catch it elsewhere.

    my $success = eval {
        local $SIG{ALRM} = sub { die "Failure" };
        alarm 10;
        do_something_long();
        alarm 0;
        1;
    };
    if (!$success) {
        warn "Timeout!\n" if $verbose;
        exit 0;
    }