"Yet another" mental block? Yes, indeed. ☹
As evidence of my earnestness and seriousness, here's a demo Perl script my friend wrote and shared with me last weekend. I refactored it into subroutines as an exercise to help me understand how forking works, which I sort of thought I did until I started toying with Parallel::ForkManager afterwards. Please rip the script to shreds if you think it will help me learn.
#!perl
use strict;
use warnings;
local $| = 1; # Autoflush output...
my $MAXIMUM_NAP_TIME = 30; # In seconds
my $POLLING_INTERVAL = 3; # In seconds
my $MAXIMUM_JOBS = 5;
my @jobs; # Array of two-dimensional job arrays [ Job Code, Process ID
+ ]
#---------------------------------------------------------------------
+--
# Enqueue initial jobs...
for (1 .. $MAXIMUM_JOBS) {
push @jobs, enqueue_job();
}
# Run jobs indefinitely...
while (1) {
my $job = shift @jobs;
push @jobs, probe_job($job);
sleep $POLLING_INTERVAL;
}
exit 0;
#---------------------------------------------------------------------
+--
sub enqueue_job {
my $code = make_code();
my $pid = take_nap();
my $job = [ $code, $pid ];
show_step('Enqueuing', $code, $pid);
return $job;
}
sub probe_job {
my $job = shift;
my $code = $job->[0];
my $pid = $job->[1];
show_step('Probing', $code, $pid);
return kill(0, $pid) ? $job : dequeue_job($job);
}
sub dequeue_job {
my $job = shift;
my $code = $job->[0];
my $pid = $job->[1];
show_step('Dequeuing', $code, $pid);
return enqueue_job();
}
sub take_nap {
my $nap_duration = int rand $MAXIMUM_NAP_TIME;
return system 1, "sleep $nap_duration";
}
BEGIN {
my $job_number = 0;
sub make_code {
return sprintf "%02d:%02d:%02d.%06d",
(localtime)[2, 1, 0], ++$job_number;
}
}
sub show_step {
my $step = shift;
my $code = shift;
my $pid = shift;
printf "%-9s Job Code %s, PID %d\n", $step, $code, $pid;
}
__END__
Thank you for the references to the helpful resources.
Jim