Bug 16011: $VERSION - Remove comments
[koha.git] / C4 / BackgroundJob.pm
1 package C4::BackgroundJob;
2
3 # Copyright (C) 2007 LibLime
4 # Galen Charlton <galen.charlton@liblime.com>
5 #
6 # This file is part of Koha.
7 #
8 # Koha is free software; you can redistribute it and/or modify it
9 # under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # Koha is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20
21 use strict;
22 #use warnings; FIXME - Bug 2505
23 use C4::Context;
24 use C4::Auth qw/get_session/;
25 use Digest::MD5;
26
27 use vars qw();
28
29 BEGIN {
30 }
31
32 =head1 NAME
33
34 C4::BackgroundJob - manage long-running jobs
35 initiated from the web staff interface
36
37 =head1 SYNOPSIS
38
39  # start tracking a job
40  my $job = C4::BackgroundJob->new($sessionID, $job_name, $job_invoker, $num_work_units);
41  my $jobID = $job->id();
42  $job->progress($work_units_processed);
43  $job->finish($job_result_hashref);
44
45  # get status and results of a job
46  my $job = C4::BackgroundJob->fetch($sessionID, $jobID);
47  my $max_work_units = $job->size();
48  my $work_units_processed = $job->progress();
49  my $job_status = $job->status();
50  my $job_name = $job->name();
51  my $job_invoker = $job->invoker();
52  my $results_hashref = $job->results();
53
54 This module manages tracking the progress and results
55 of (potentially) long-running jobs initiated from 
56 the staff user interface.  Such jobs can include
57 batch MARC and patron record imports.
58
59 =head1 METHODS
60
61 =head2 new
62
63  my $job = C4::BackgroundJob->new($sessionID, $job_name, $job_invoker, $num_work_units);
64
65 Create a new job object and set its status to 'running'.  C<$num_work_units>
66 should be a number representing the size of the job; the units of the
67 job size are up to the caller and could be number of records, 
68 number of bytes, etc.
69
70 =cut
71
72 sub new {
73     my $class = shift;
74     my ($sessionID, $job_name, $job_invoker, $num_work_units) = @_;
75
76     my $self = {};
77     $self->{'sessionID'} = $sessionID;
78     $self->{'name'} = $job_name;
79     $self->{'invoker'} = $job_invoker;
80     $self->{'size'} = $num_work_units;
81     $self->{'progress'} = 0;
82     $self->{'status'} = "running";
83     $self->{'jobID'} = Digest::MD5::md5_hex(Digest::MD5::md5_hex(time().{}.rand().{}.$$));
84     $self->{'extra_values'} = {};
85
86     bless $self, $class;
87     $self->_serialize();
88
89     return $self;
90 }
91
92 # store object in CGI session
93 sub _serialize {
94     my $self = shift;
95
96     my $prefix = "job_" . $self->{'jobID'};
97     my $session = get_session($self->{'sessionID'});
98     $session->param($prefix, $self);
99     $session->flush();
100 }
101
102 =head2 id
103
104  my $jobID = $job->id();
105
106 Read-only accessor for job ID.
107
108 =cut
109
110 sub id {
111     my $self = shift;
112     return $self->{'jobID'};
113 }
114
115 =head2 name
116
117  my $name = $job->name();
118  $job->name($name);
119
120 Read/write accessor for job name.
121
122 =cut
123
124 sub name {
125     my $self = shift;
126     if (@_) {
127         $self->{'name'} = shift;
128         $self->_serialize();
129     } else {
130         return $self->{'name'};
131     }
132 }
133
134 =head2 invoker
135
136  my $invoker = $job->invoker();
137 i $job->invoker($invoker);
138
139 Read/write accessor for job invoker.
140
141 =cut
142
143 sub invoker {
144     my $self = shift;
145     if (@_) {
146         $self->{'invoker'} = shift;
147         $self->_serialize();
148     } else {
149         return $self->{'invoker'};
150     }
151 }
152
153 =head2 progress
154
155  my $progress = $job->progress();
156  $job->progress($progress);
157
158 Read/write accessor for job progress.
159
160 =cut
161
162 sub progress {
163     my $self = shift;
164     if (@_) {
165         $self->{'progress'} = shift;
166         $self->_serialize();
167     } else {
168         return $self->{'progress'};
169     }
170 }
171
172 =head2 status
173
174  my $status = $job->status();
175
176 Read-only accessor for job status.
177
178 =cut
179
180 sub status {
181     my $self = shift;
182     return $self->{'status'};
183 }
184
185 =head2 size
186
187  my $size = $job->size();
188  $job->size($size);
189
190 Read/write accessor for job size.
191
192 =cut
193
194 sub size {
195     my $self = shift;
196     if (@_) {
197         $self->{'size'} = shift;
198         $self->_serialize();
199     } else {
200         return $self->{'size'};
201     }
202 }
203
204 =head2 finish
205
206  $job->finish($results_hashref);
207
208 Mark the job as finished, setting its status to 'completed'.
209 C<$results_hashref> should be a reference to a hash containing
210 the results of the job.
211
212 =cut
213
214 sub finish {
215     my $self = shift;
216     my $results_hashref = shift;
217     $self->{'status'} = 'completed';
218     $self->{'results'} = $results_hashref;
219     $self->_serialize();
220 }
221
222 =head2 results
223
224  my $results_hashref = $job->results();
225
226 Retrieve the results of the current job.  Returns undef 
227 if the job status is not 'completed'.
228
229 =cut
230
231 sub results {
232     my $self = shift;
233     return unless $self->{'status'} eq 'completed';
234     return $self->{'results'};
235 }
236
237 =head2 fetch
238
239  my $job = C4::BackgroundJob->fetch($sessionID, $jobID);
240
241 Retrieve a job that has been serialized to the database. 
242 Returns C<undef> if the job does not exist in the current 
243 session.
244
245 =cut
246
247 sub fetch {
248     my $class = shift;
249     my $sessionID = shift;
250     my $jobID = shift;
251
252     my $session = get_session($sessionID);
253     my $prefix = "job_$jobID";
254     unless (defined $session->param($prefix)) {
255         return;
256     }
257     my $self = $session->param($prefix);
258     bless $self, $class;
259     return $self;
260 }
261
262 =head2 set
263
264 =over 4
265
266 =item $job->set($hashref);
267
268 =back
269
270 Set some variables into the hashref.
271 These variables can be retrieved using the get method.
272
273 =cut
274
275 sub set {
276     my ($self, $hashref) = @_;
277     while ( my ($k, $v) = each %$hashref ) {
278         $self->{extra_values}->{$k} = $v;
279     }
280     $self->_serialize();
281     return;
282 }
283
284 =head2 get
285
286 =over 4
287
288 =item $value = $job->get($key);
289
290 =back
291
292 Get a variable which has been previously stored with the set method.
293
294 =cut
295
296 sub get {
297     my ($self, $key) = @_;
298     return $self->{extra_values}->{$key};
299 }
300
301
302 =head2 clear
303
304 =over 4
305
306 =item $job->clear();
307
308 =back
309
310 Clear the job from the current session.
311
312 =cut
313
314 sub clear {
315     my $self = shift;
316     get_session($self->{sessionID})->clear('job_' . $self->{jobID});
317 }
318
319
320 1;
321 __END__
322
323 =head1 AUTHOR
324
325 Koha Development Team <http://koha-community.org/>
326
327 Galen Charlton <galen.charlton@liblime.com>
328
329 =cut