aboutsummaryrefslogtreecommitdiff
path: root/lib/App/Beam/History.pm
blob: 0421c3e7e5ece446dbc315895ea78839dd35c1ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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.