File Coverage

blib/lib/App/OverWatch/ServiceLock.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1              
2             package App::OverWatch::ServiceLock;
3             # ABSTRACT: ServiceLock base class
4              
5 1     1   1809 use strict;
  1         1  
  1         37  
6 1     1   4 use warnings;
  1         1  
  1         19  
7              
8 1     1   28 use App::OverWatch::DB;
  0            
  0            
9             use App::OverWatch::Lock;
10              
11             use Module::Load qw( load );
12              
13             sub new {
14             my $class = shift;
15             my $rh_options = shift || {};
16              
17             my $DB = $rh_options->{db} // die "Require 'db'";
18              
19             my $type = $DB->type();
20              
21             my $subclass = $class . '::' . $type;
22             load($subclass);
23              
24             my $self = bless( {}, $subclass );
25              
26             $self->{DB} = $DB;
27              
28             return $self;
29             }
30              
31             sub create_lock {
32             my $self = shift;
33             my $rh_args = shift;
34              
35             my $system = $rh_args->{system} || die "Error: require 'system'";
36              
37             my $now_sql = $self->generate_now_sql();
38              
39             my $sql =<<"SQL";
40             INSERT INTO
41             servicelocks ( system, worker, status, mtime )
42             VALUES
43             ( ?, '', 'UNLOCKED', $now_sql )
44             SQL
45              
46             my $ret = $self->{DB}->dbix_run( $sql, $system );
47             return $ret;
48             }
49              
50             sub get_all_locks {
51             my $self = shift;
52              
53             my $sql =<<"SQL";
54             SELECT
55             *
56             FROM
57             servicelocks
58             SQL
59              
60             my $sth = $self->{DB}->dbix_select( $sql );
61             return undef if (!defined($sth));
62             my @locks;
63             while ( my $rh_row = $sth->fetchrow_hashref() ) {
64             my $Lock = App::OverWatch::Lock->new($rh_row);
65             push(@locks, $Lock);
66             }
67             return @locks;
68             }
69              
70             sub get_lock {
71             my $self = shift;
72             my $rh_args = shift;
73              
74             my $system = $rh_args->{system} || die "Error: require 'system'";
75              
76             my $sql =<<"SQL";
77             SELECT
78             *
79             FROM
80             servicelocks
81             WHERE
82             system = ?
83             SQL
84              
85             my $sth = $self->{DB}->dbix_select( $sql, $system );
86             return undef if (!defined($sth));
87             my $rh_row = $sth->fetchrow_hashref();
88             die "Error: No such lock '$system'\n"
89             if ($sth->rows() == 0 || !defined($rh_row));
90             my $Lock = App::OverWatch::Lock->new($rh_row);
91             return $Lock;
92             }
93              
94             ##
95              
96             sub try_lock {
97             my $self = shift;
98             my $rh_args = shift;
99              
100             my $system = $rh_args->{system} || die "Error: require 'system'";
101             my $worker = $rh_args->{worker} || die "Error: require 'worker'";
102             my $expiry = $rh_args->{expiry} // 0;
103             my $text = $rh_args->{text} || die "Error: require 'text'";
104              
105             my $expiry_sql = $self->timestamp_calculate_sql($expiry);
106             my $now_sql = $self->generate_now_sql();
107              
108             my $sql =<<"SQL";
109             UPDATE
110             servicelocks
111             SET
112             worker = ?,
113             status = 'LOCKED',
114             expiry = $expiry_sql,
115             text = ?,
116             mtime = $now_sql
117             WHERE
118             system = ? AND
119             (
120             status = 'UNLOCKED' OR
121             (
122             expiry IS NOT NULL AND expiry < $now_sql
123             )
124             )
125             SQL
126              
127             my $ret = $self->{DB}->dbix_run( $sql, $worker, $text, $system );
128             return $ret == 1 ? 1 : 0;
129             }
130              
131             sub try_update {
132             my $self = shift;
133             my $rh_args = shift;
134              
135             my $system = $rh_args->{system} || die "Error: require 'system'";
136             my $worker = $rh_args->{worker} || die "Error: require 'worker'";
137             my $expiry = $rh_args->{expiry};
138             my $text = $rh_args->{text} || die "Error: require 'text'";
139              
140             my $full_expiry_sql = "";
141             if (defined($expiry)) {
142             my $expiry_sql = $self->timestamp_calculate_sql($expiry);
143             $full_expiry_sql = "expiry = $expiry_sql,";
144             }
145              
146             my $now_sql = $self->generate_now_sql();
147              
148             my $sql =<<"SQL";
149             UPDATE
150             servicelocks
151             SET
152             $full_expiry_sql
153             text = ?,
154             mtime = $now_sql
155             WHERE
156             system = ? AND
157             worker = ? AND
158             status = 'LOCKED'
159             SQL
160              
161             my $ret = $self->{DB}->dbix_run( $sql, $text, $system, $worker );
162             return $ret == 1 ? 1 : 0;
163             }
164              
165             sub try_unlock {
166             my $self = shift;
167             my $rh_args = shift;
168              
169             my $system = $rh_args->{system} || die "Error: require 'system'";
170             my $worker = $rh_args->{worker} || die "Error: require 'worker'";
171              
172             my $now_sql = $self->generate_now_sql();
173              
174             my $sql =<<"SQL";
175             UPDATE
176             servicelocks
177             SET
178             worker = '',
179             status = 'UNLOCKED',
180             expiry = NULL,
181             text = '',
182             mtime = $now_sql
183             WHERE
184             system = ? AND
185             worker = ? AND
186             status = 'LOCKED'
187             SQL
188              
189             my $ret = $self->{DB}->dbix_run( $sql, $system, $worker );
190             return $ret == 1 ? 1 : 0;
191             }
192              
193             sub force_unlock {
194             my $self = shift;
195             my $rh_args = shift;
196              
197             my $system = $rh_args->{system} || die "Error: require 'system'";
198              
199             my $sql =<<"SQL";
200             UPDATE
201             servicelocks
202             SET
203             worker = '',
204             status = 'UNLOCKED',
205             expiry = NULL,
206             text = ''
207             WHERE
208             system = ? AND
209             status = 'LOCKED'
210             SQL
211              
212             my $ret = $self->{DB}->dbix_run( $sql, $system );
213             return $ret == 1 ? 1 : 0;
214             }
215              
216             1;
217              
218             __END__