Apache-Watchdog-RunAway

 view release on metacpan or  search on metacpan

RunAway.pm  view on Meta::CPAN


# timeout before counted as hang (in seconds)
# 0 means deactivated
$Apache::Watchdog::RunAway::TIMEOUT = 0;

# polling intervals in seconds
$Apache::Watchdog::RunAway::POLLTIME = 60;

# debug mode
$Apache::Watchdog::RunAway::DEBUG = 0;

# lock file
$Apache::Watchdog::RunAway::LOCK_FILE = "/tmp/safehang.lock";

# log file
$Apache::Watchdog::RunAway::LOG_FILE = "/tmp/safehang.log";

# scoreboard URL
$Apache::Watchdog::RunAway::SCOREBOARD_URL = "http://localhost/scoreboard";

# give details about the request that was hanging
$Apache::Watchdog::RunAway::VERBOSE = 0;

########## internal variables #########

# request processing times cache
my %req_proc_time = ();

# current request number
my %req_number = ();

my $log_fh;

# check whether the monitor is already running
# returns the PID if lockfile exists
##############
sub is_running {

    return 0 unless -e $Apache::Watchdog::RunAway::LOCK_FILE;

    my $pid = get_proc_pid();

    warn <<EOT if $Apache::Watchdog::RunAway::DEBUG;
$0 is already running (proc $pid).
Locked in $Apache::Watchdog::RunAway::LOCK_FILE.
EOT

    return $pid;

}


# returns the PID if lockfile exists or 0
################
sub get_proc_pid {

    my $fh = Symbol::gensym();
    open $fh, $Apache::Watchdog::RunAway::LOCK_FILE
        or die "Cannot open $Apache::Watchdog::RunAway::LOCK_FILE: $!";
    chomp (my $pid = <$fh>);
    # untaint
    $pid = $pid =~ /^(\d+)$/ ? $1 : 0;
    close $fh;

    return $pid;
}


# create the lockfile and put the PID inside
##############
sub lock {

    my $fh = Symbol::gensym();
    open $fh, ">".$Apache::Watchdog::RunAway::LOCK_FILE
        or die "Cannot open $Apache::Watchdog::RunAway::LOCK_FILE: $!";
    flock $fh, 2;
    seek $fh, 0, 0;
    print $fh $$;
    close $fh;

}


#################
sub stop_monitor {

    unless (-e $Apache::Watchdog::RunAway::LOCK_FILE) {
        warn <<EOT if $Apache::Watchdog::RunAway::DEBUG;
$0: Lockfile $Apache::Watchdog::RunAway::LOCK_FILE does not exist. Exiting...
EOT
        return;
    }

    my $pid = get_proc_pid();

    my $killed = kill 15, $pid if $pid;
    warn "$0: monitor process $pid was killed\n" 
        if $killed && $Apache::Watchdog::RunAway::DEBUG;

    # unlock the lockfile
    unlink $Apache::Watchdog::RunAway::LOCK_FILE;

}


##################
sub start_detached_monitor {

    defined (my $watchdog_pid = fork) or die "Cannot fork: $!\n";

    if ($watchdog_pid) {
        warn "detached monitor pid $watchdog_pid started\n"
            if $Apache::Watchdog::RunAway::DEBUG;
        return $watchdog_pid;
    }
    else {
        start_monitor();
        CORE::exit();
    }
}



( run in 2.083 seconds using v1.01-cache-2.11-cpan-5b529ec07f3 )