#!/usr/bin/perl

# run as www-data (same as /run/hilis4/*.pid owner)
# perl script/kidreaper.pl <service> <MB>
# adapted from http://www.catalystframework.org/calendar/2007/18:
#   * changed kB to MB
#   * used IPC::System::Simple to capture ppid from service-name

use lib '/home/raj/perl5/lib/perl5';
use IPC::System::Simple qw(capture);
use Data::Printer;
use Modern::Perl;

my ($service, $max_mb) = @ARGV;
die "Usage: $0 <service_name> <ram_limit_in_MB>\n" unless $service && $max_mb;

my $ppid = capture("cat /run/hilis4/$service.pid") or die $!; p $ppid;
my $kids;

if ( open ($kids, "/bin/ps -o pid=,vsz= --ppid $ppid|") ) {
    my @goners;

    while (<$kids>) {
        chomp;
        my ($pid, $mem) = split; # p $mem;

        # ps shows KB.  we want MBytes.
        $mem /= 1024;

        if ($mem >= $max_mb) {
            say sprintf "process %s mem [%s MB] > permitted [%s MB]",
                $pid, $mem, $max_mb;
            push @goners, $pid;
        }
    }

    close($kids);

    if (@goners) {
        # kill them slowly, so that all connection serving
        # children don't suddenly die at once.

        foreach my $victim (@goners) { # p $victim;
           # kill 'HUP', $victim;
           sleep 2;
        }
    }
}
else {
    die "Can't get process list: $!\n";
}
