Skip to content

Instantly share code, notes, and snippets.

@marshyon
Last active August 29, 2015 14:02
Show Gist options
  • Save marshyon/2f3e76432e7d041dbb08 to your computer and use it in GitHub Desktop.
Save marshyon/2f3e76432e7d041dbb08 to your computer and use it in GitHub Desktop.
using Parallel::ForkManager as a simple scheduler to maintain a fixed number of long running forked processes
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
use Parallel::ForkManager 0.7.6;
use Time::HiRes qw (sleep);
use POSIX qw(strftime);
my $tmp_dir = '/tmp';
my $MAX_PROCESSES = 8;
my $pm = Parallel::ForkManager->new($MAX_PROCESSES, $tmp_dir);
my %runners = (
'sneezy' => 0,
'sad' => 0,
'angry' => 0,
'lazy' => 0,
'sleepy' => 0,
'hippy' => 0,
'snory' => 0,
'smelly' => 0
);
$pm -> run_on_finish ( # called BEFORE the first call to start()
sub {
my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_;
if (defined($data_structure_reference)) {
my $string = ${$data_structure_reference};
$runners{$string} = 0 if $string;
} else {
print qq|No message received from child process $pid!\n|;
}
}
);
while(1) {
my $current_runner = '';
# pick a runner name
RUNNER:
foreach my $name (keys(%runners)) {
if($runners{$name} == 0) {
$runners{$name}++;
$current_runner = $name;
last RUNNER;
}
}
# fork child process
my $pid = $pm->start() and next;
# sleep untill time to run
my $iter = 0;
my $interval = 300;
my $max_iter = $interval / 0.2;
# sleep untill it is time to do some work
SLEEP:
while($iter < $max_iter) {
sleep (0.2);
$iter++;
my $now = time();
my $rem = $now % $interval;
if($rem < 1) {
# run now
my $now_string = strftime "%Y-%m-%d %H:%M:%S", gmtime;
log_it($current_runner, "starting run at $now_string");
sleep 230;
sleep int(rand(100));
log_it($current_runner, "finished run from $now_string");
last SLEEP;
}
}
# return name of this runner to parent process
$pm->finish(0, \$current_runner);
}
sub log_it {
my ($name, $mess) = @_;
chomp($mess);
my $log = $name . '.log';
my $now_string = strftime "%Y-%m-%d %H:%M:%S", gmtime;
open my $of, ">>", $log or die "can't open $log for write : $!\n";
print $of $now_string . " :: " . $name . " :: " . $mess . "\n";
close $of;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment