Merge branch 'bug_8200' into 3.12-master
[koha.git] / C4 / BackgroundJob.pm
blob6830565ce4114fa7dacfef218f8c589599877318
1 package C4::BackgroundJob;
3 # Copyright (C) 2007 LibLime
4 # Galen Charlton <galen.charlton@liblime.com>
6 # This file is part of Koha.
8 # Koha is free software; you can redistribute it and/or modify it under the
9 # terms of the GNU General Public License as published by the Free Software
10 # Foundation; either version 2 of the License, or (at your option) any later
11 # version.
13 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
14 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License along
18 # with Koha; if not, write to the Free Software Foundation, Inc.,
19 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 use strict;
22 #use warnings; FIXME - Bug 2505
23 use C4::Context;
24 use C4::Auth qw/get_session/;
25 use Digest::MD5;
27 use vars qw($VERSION);
29 BEGIN {
30 # set the version for version checking
31 $VERSION = 3.07.00.049;
34 =head1 NAME
36 C4::BackgroundJob - manage long-running jobs
37 initiated from the web staff interface
39 =head1 SYNOPSIS
41 # start tracking a job
42 my $job = C4::BackgroundJob->new($sessionID, $job_name, $job_invoker, $num_work_units);
43 my $jobID = $job->id();
44 $job->progress($work_units_processed);
45 $job->finish($job_result_hashref);
47 # get status and results of a job
48 my $job = C4::BackgroundJob->fetch($sessionID, $jobID);
49 my $max_work_units = $job->size();
50 my $work_units_processed = $job->progress();
51 my $job_status = $job->status();
52 my $job_name = $job->name();
53 my $job_invoker = $job->invoker();
54 my $results_hashref = $job->results();
56 This module manages tracking the progress and results
57 of (potentially) long-running jobs initiated from
58 the staff user interface. Such jobs can include
59 batch MARC and patron record imports.
61 =head1 METHODS
63 =head2 new
65 my $job = C4::BackgroundJob->new($sessionID, $job_name, $job_invoker, $num_work_units);
67 Create a new job object and set its status to 'running'. C<$num_work_units>
68 should be a number representing the size of the job; the units of the
69 job size are up to the caller and could be number of records,
70 number of bytes, etc.
72 =cut
74 sub new {
75 my $class = shift;
76 my ($sessionID, $job_name, $job_invoker, $num_work_units) = @_;
78 my $self = {};
79 $self->{'sessionID'} = $sessionID;
80 $self->{'name'} = $job_name;
81 $self->{'invoker'} = $job_invoker;
82 $self->{'size'} = $num_work_units;
83 $self->{'progress'} = 0;
84 $self->{'status'} = "running";
85 $self->{'jobID'} = Digest::MD5::md5_hex(Digest::MD5::md5_hex(time().{}.rand().{}.$$));
87 bless $self, $class;
88 $self->_serialize();
90 return $self;
93 # store object in CGI session
94 sub _serialize {
95 my $self = shift;
97 my $prefix = "job_" . $self->{'jobID'};
98 my $session = get_session($self->{'sessionID'});
99 $session->param($prefix, $self);
100 $session->flush();
103 =head2 id
105 my $jobID = $job->id();
107 Read-only accessor for job ID.
109 =cut
111 sub id {
112 my $self = shift;
113 return $self->{'jobID'};
116 =head2 name
118 my $name = $job->name();
119 $job->name($name);
121 Read/write accessor for job name.
123 =cut
125 sub name {
126 my $self = shift;
127 if (@_) {
128 $self->{'name'} = shift;
129 $self->_serialize();
130 } else {
131 return $self->{'name'};
135 =head2 invoker
137 my $invoker = $job->invoker();
138 i $job->invoker($invoker);
140 Read/write accessor for job invoker.
142 =cut
144 sub invoker {
145 my $self = shift;
146 if (@_) {
147 $self->{'invoker'} = shift;
148 $self->_serialize();
149 } else {
150 return $self->{'invoker'};
154 =head2 progress
156 my $progress = $job->progress();
157 $job->progress($progress);
159 Read/write accessor for job progress.
161 =cut
163 sub progress {
164 my $self = shift;
165 if (@_) {
166 $self->{'progress'} = shift;
167 $self->_serialize();
168 } else {
169 return $self->{'progress'};
173 =head2 status
175 my $status = $job->status();
177 Read-only accessor for job status.
179 =cut
181 sub status {
182 my $self = shift;
183 return $self->{'status'};
186 =head2 size
188 my $size = $job->size();
189 $job->size($size);
191 Read/write accessor for job size.
193 =cut
195 sub size {
196 my $self = shift;
197 if (@_) {
198 $self->{'size'} = shift;
199 $self->_serialize();
200 } else {
201 return $self->{'size'};
205 =head2 finish
207 $job->finish($results_hashref);
209 Mark the job as finished, setting its status to 'completed'.
210 C<$results_hashref> should be a reference to a hash containing
211 the results of the job.
213 =cut
215 sub finish {
216 my $self = shift;
217 my $results_hashref = shift;
218 $self->{'status'} = 'completed';
219 $self->{'results'} = $results_hashref;
220 $self->_serialize();
223 =head2 results
225 my $results_hashref = $job->results();
227 Retrieve the results of the current job. Returns undef
228 if the job status is not 'completed'.
230 =cut
232 sub results {
233 my $self = shift;
234 return unless $self->{'status'} eq 'completed';
235 return $self->{'results'};
238 =head2 fetch
240 my $job = C4::BackgroundJob->fetch($sessionID, $jobID);
242 Retrieve a job that has been serialized to the database.
243 Returns C<undef> if the job does not exist in the current
244 session.
246 =cut
248 sub fetch {
249 my $class = shift;
250 my $sessionID = shift;
251 my $jobID = shift;
253 my $session = get_session($sessionID);
254 my $prefix = "job_$jobID";
255 unless (defined $session->param($prefix)) {
256 return;
258 my $self = $session->param($prefix);
259 bless $self, $class;
260 return $self;
264 __END__
266 =head1 AUTHOR
268 Koha Development Team <http://koha-community.org/>
270 Galen Charlton <galen.charlton@liblime.com>
272 =cut