File Coverage

lib/App/MtAws/QueueJob/Iterator.pm
Criterion Covered Total %
statement 55 56 100.0
branch 21 22 100.0
condition 2 2 100.0
subroutine 12 12 100.0
pod 0 6 0.0
total 90 98 93.8


line stmt bran cond sub pod time code
1             # mt-aws-glacier - Amazon Glacier sync client
2             # Copyright (C) 2012-2014 Victor Efimov
3             # http://mt-aws.com (also http://vs-dev.com) vs@vs-dev.com
4             # License: GPLv3
5             #
6             # This file is part of "mt-aws-glacier"
7             #
8             # mt-aws-glacier is free software: you can redistribute it and/or modify
9             # it 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             # mt-aws-glacier is distributed in the hope that it will be useful,
14             # but 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 this program. If not, see <http://www.gnu.org/licenses/>.
20              
21             package App::MtAws::QueueJob::Iterator;
22              
23             our $VERSION = '1.114_2';
24              
25 9     9   708 use strict;
  9         14  
  9         224  
26 9     9   34 use warnings;
  9         10  
  9         180  
27 9     9   30 use Carp;
  9         11  
  9         373  
28              
29 9     9   561 use App::MtAws::QueueJobResult;
  9         13  
  9         499  
30 9     9   82 use base 'App::MtAws::QueueJob';
  9         11  
  9         4364  
31              
32             sub init
33             {
34 137     137 0 159 my ($self) = @_;
35              
36 137 100       541 $self->{iterator}||confess "iterator required";
37 136   100     365 $self->{maxcnt} ||= 30;
38 136         230 $self->{jobs} = {};
39 136         184 $self->{job_autoincrement} = 0;
40 136         341 $self->enter('itt_only');
41             }
42              
43              
44             sub get_next_itt
45             {
46 578     578 0 524 my ($self) = @_;
47 578         1418 my $next_job = $self->{iterator}->();
48 578 100       2409 if ($next_job) {
49 469         489 my $i = ++$self->{job_autoincrement};
50 469         849 $self->{jobs}{$i} = $next_job;
51             }
52 578         962 $next_job;
53             }
54              
55             sub find_next_job
56             {
57 1813     1813 0 1481 my ($self) = @_;
58 1813         1673 my $maxcnt = $self->{maxcnt};
59 1813         1438 for my $job_id (keys %{$self->{jobs}}) { # Random order of jobs
  1813         3738  
60 2370         2936 my $job = $self->{jobs}{$job_id};
61 2370         4490 my $res = $job->next();
62            
63             # uncoverable branch false count:3
64 2370 100       4107 if ($res->{code} eq JOB_WAIT) {
    100          
    50          
65 1387 100       3028 return JOB_WAIT unless --$maxcnt;
66             } elsif ($res->{code} eq JOB_DONE) {
67 469         552 delete $self->{jobs}{$job_id};
68 469         2083 return JOB_RETRY;
69              
70             } elsif ($res->{code} eq JOB_OK) {
71             return task($res->{task}, sub {
72 514     514   1185 $res->{task}{cb_task_proxy}->(@_);
73 514         1143 return;
74 514         1876 });
75             } else {
76             # uncoverable statement
77 0         0 confess;
78             }
79             }
80 819         2099 return;
81             }
82              
83             # there are no pending jobs, only iterator available
84             sub on_itt_only
85             {
86 109     109 0 135 my ($self) = @_;
87              
88 109 100       211 if ($self->get_next_itt) {
89 104         301 return state 'itt_and_jobs'; # immediatelly switch to other state
90             } else {
91 5         20 return JOB_DONE;
92             }
93             }
94              
95              
96             # both jobs and iterator available
97             sub on_itt_and_jobs
98             {
99 1328     1328 0 1234 my ($self) = @_;
100 1328 100       1786 if (my @r = $self->find_next_job) { # try to process one pending job
    100          
101 859         2363 return @r;
102             } elsif ($self->get_next_itt) {
103 365         916 return JOB_RETRY # otherwise, get new job from iteartor and retry
104             } else {
105 104         246 return state 'jobs_only' # no jobs in iterator? - switch to jobs_only
106             }
107             }
108              
109             sub on_jobs_only
110             {
111 485     485 0 495 my ($self) = @_;
112 485 100       720 if (my @r = $self->find_next_job) {
113 135         377 return @r; # can be 'wait' here
114             } else {
115 350 100       291 return keys %{$self->{jobs}} ? JOB_WAIT : state "done";
  350         1189  
116             }
117             }
118              
119             1;