aboutsummaryrefslogtreecommitdiff
path: root/lib/App/Beam/History.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/App/Beam/History.pm')
-rw-r--r--lib/App/Beam/History.pm76
1 files changed, 76 insertions, 0 deletions
diff --git a/lib/App/Beam/History.pm b/lib/App/Beam/History.pm
new file mode 100644
index 0000000..0421c3e
--- /dev/null
+++ b/lib/App/Beam/History.pm
@@ -0,0 +1,76 @@
+package App::Beam::History;
+
+use strict;
+use Carp;
+use App::Beam::History::Record;
+use App::Beam::History::Entry qw(:state);
+
+require Exporter;
+our @ISA = qw(Exporter);
+
+use Fcntl qw(:flock SEEK_SET);
+use Storable qw(fd_retrieve nstore_fd);
+
+sub new {
+ my $class = shift;
+ my $filename = shift;
+ my $rounds = shift;
+ my $levels = shift;
+
+ my $self = bless { filename => $filename }, $class;
+
+ my $v;
+ local %_ = @_;
+ if (defined($v = delete($_{dry_run}))) {
+ $self->{dry_run} = $v;
+ }
+
+ if (keys(%_)) {
+ croak "unknown or unhandled parameters: ".join(',', keys(%_));
+ }
+
+ unless (open($self->{filehandle}, '+>>', $filename)) {
+ croak "can't open file $filename: $!";
+ }
+ unless (flock($self->{filehandle}, LOCK_EX | LOCK_NB)) {
+ croak "can't lock file $filename: $!";
+ }
+ seek($self->{filehandle}, 0, SEEK_SET);
+ if ((stat($self->{filehandle}))[7] == 0) {
+ $self->{history} = [];
+ unshift @{$self->{history}}, new App::Beam::History::Record;
+ } else {
+ $self->{history} = fd_retrieve($self->{filehandle})
+ or croak "can't retrieve status from $self->{filehandle}: $!";
+ if (ref($self->{history}) ne 'ARRAY') {
+ croak "$self->{filename}: malformed status file";
+ }
+ unshift @{$self->{history}},
+ new App::Beam::History::Record(prev => $self->{history}[0],
+ rounds => $rounds,
+ levels => $levels);
+ }
+ return $self;
+}
+
+sub records {
+ my $self = shift;
+ return @{$self->{history}};
+}
+
+sub top {
+ my ($self, $idx) = @_;
+ return $self->{history}[$idx];
+}
+
+sub save {
+ my $self = shift;
+ if (!$self->{dry_run} && $self->top->state != STATE_PENDING) {
+ seek($self->{filehandle}, 0, SEEK_SET);
+ truncate($self->{filehandle}, 0);
+ nstore_fd($self->{history}, $self->{filehandle});
+ }
+ flock($self->{filehandle}, LOCK_UN);
+ close($self->{filehandle});
+}
+

Return to:

Send suggestions and report system problems to the System administrator.