I am researching a way to interrupt the execution of the Perl script below in a way that I can save at what point the interaction was and I can run the next time starting from this interaction. Basically I saw other people speaking "save Perl's execution in the state in which it was". I'm looking inside the script and trying to understand how I can extract the interaction number and print out to a file and then reinsert in the script as the initial index of the next starting running.
use strict;
use warnings;
sub powerset(&@) {
my $callback = shift;
my $bitmask = '';
my $bytes = @_/8;
{
my @indices = grep vec($bitmask, $_, 1), 0..$#_;
$callback->( @_[@indices] );
++vec($bitmask, $_, 8) and last for 0 .. $bytes;
redo if @indices != @_;
}
}
powerset { print "[@_]\n" } 1..5;
my $i = 0;
For sample: Let's say I want the powerset of a set of 1..50, and then at the time I interrupt the execution the last line printed on the output is [1 2 3 4 6 7 8 11 12 13 15 16 17]
. Then on the second startup of the script execution I just want to iterate just about the respective indice to the line [1 2 3 4 6 7 8 11 12 13 15 16 17]
that was printed, I do not want to redo the iterations that have already had the result printed on the first run of the Perl file.
My goal is to be able to start a first run of file.pl
and then print the output in an out.txt
file, perl file.pl > out.txt
, and then move the out.txt
file to another directory (ie delete out.txt from the current directory). Then I must be able to continue interaction from the respective index to the line [1 2 3 4 6 7 8 11 12 13 15 16 17]
that has already been printed.
Note: I know: "to suspend the program, you'd type ^ z (= ctrl-z) 1 while the program is running. Then Type BG TO SEND THE (STOPPED) Process in The Background. To Resume It Again, Type FG (or fg in case you have severe backgrounded - Type Jobs to List Them). " But that's not quite what I expected.
Perhaps what you are looking for can be demonstrated with following code snippet implementing checkpoint
approach.
The code implements two functions to store/restore execution stage
and data_set
.
If the code is interrupted in the middle of the execution, then following re-run will continue starting after completed stage
by restoring saved earlier data_set
.
NOTE: for demonstration put exit
after store_checkpoint($data)
at the end of STAGE2
. Run the script once, remove added exit
and re-run the script once more.
use strict;
use warnings;
use feature 'say';
use YAML;
use Data::Dumper;
my $checkpoint = 'checkpoint.dat';
my $data;
restore_checkpoint() if -e $checkpoint;
STAGE1:
$data->{data_set} = [ title => 'scientist', age => 27, address => '123 street, NY 12345 USA' ];
$data->{next_stage} = 'STAGE2';
store_checkpoint($data);
STAGE2:
$data->{data_set} = [ title => 'professor', age => 45, address => '234 street, WA 98230 USA' ];
$data->{next_stage} = 'STAGE3';
store_checkpoint($data);
STAGE3:
$data->{data_set} = [ title => 'doctor', age => 53, address => '345 street, OK 56789 USA' ];
$data->{next_stage} = 'STAGE4';
store_checkpoint($data);
STAGE4:
$data->{data_set} = [ title => 'CEO', age => 38, address => '456 street, MA 54321 USA' ];
$data->{next_stage} = 'STAGE5';
store_checkpoint($data);
STAGE5:
say 'Done';
sub store_checkpoint {
my $data = shift;
say 'INFO: save_checkpoint ' . $data->{next_stage};
open my $fh, '>', $checkpoint
or die "Couldn't open $checkpoint";
say $fh Dump($data);
close $fh;
}
sub restore_checkpoint {
say 'INFO: restore_checkpoint';
open my $fh, '<', $checkpoint
or die "Couldn't open $checkpoint";
my $yaml = do { local $/; <$fh> };
close $fh;
$data = Load($yaml);
say Dumper($data);
say 'INFO: continue stage ' . $data->{next_stage};
goto $data->{next_stage};
}