Last active
August 29, 2015 14:02
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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