philkime has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to use alarm() to log/send email/open ticket after a process has been running for a certain amount of time:
local $SIG{ALRM} = sub { write_log('TIMEOUT ALERT'); }; alarm 20; my ($run_ok, undef, $full_buf, undef, undef) = run(command => $cmd); alarm 0;
This is using IPC::Run to run the command. I am running many commands, some taking more than 20 seconds but the message "TIMEOUT ALERT" never appears in the log and all commands run to completion as normal. I don't want to kill anything (contrary to most alarm() examples I find), I just want to let the command run but send some warning somewhere if it takes X amount of time. Is there something obviously wrong here?

Replies are listed 'Best First'.
Re: $SIG{ALRM} to just log something?
by kcott (Archbishop) on Apr 17, 2014 at 01:20 UTC

    G'day philkime,

    "This is using IPC::Run to run the command."

    Have you looked in the "Timeouts and Timers" section of IPC::Run?

    "I don't want to kill anything (contrary to most alarm() examples I find), I just want to let the command run but send some warning somewhere if it takes X amount of time."

    At least for an example of a technique you can use to achieve this, see "Check for a new line". You'll need to look at my initial response for the main code (this does kill the process); then at my subsequent response which shows a small change to intermittently output a message and not kill the process.

    [See also: alarm and "perlipc: Signals"]

    -- Ken

Re: $SIG{ALRM} to just log something?
by Anonymous Monk on Apr 16, 2014 at 20:27 UTC

    FWIW/AFAIK alarm interrupts your code, so you can't simply log something, then resume the thing you were interrupting ... the thing was interrupted, its finished

    OTOH, the reason run() isn't interrupted is probably a safe/unsafe signals issue ... see how to use angle operator with timeout?/Re^3: how to use angle operator with timeout?

    You can probably get around this by launching the run in a background process ( Proc::Background, use a file for ipc (save output of run ), then using sleep instead of alarm, then do your logging if the process isn't finished, then wait for it to finally finish, then read output of run from the file

    Or similar strategy by using threads (ipc through shared hash of Q instead of files

Re: $SIG{ALRM} to just log something?
by zentara (Cardinal) on Apr 17, 2014 at 17:36 UTC
Re: $SIG{ALRM} to just log something?
by Bloodnok (Vicar) on Apr 17, 2014 at 09:41 UTC
    Aside from the previous pertinent suggestions, Sys::SigAction &/or Time::Out might well, IMO, prove useful to you.

    A user level that continues to overstate my experience :-))