| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
1
|
|
|
1
|
|
909
|
use 5.008; |
|
|
1
|
|
|
|
|
6
|
|
|
|
1
|
|
|
|
|
103
|
|
|
2
|
1
|
|
|
1
|
|
9
|
use strict; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
43
|
|
|
3
|
1
|
|
|
1
|
|
8
|
use warnings; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
57
|
|
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
package Data::Conveyor::Exception::Container; |
|
6
|
|
|
|
|
|
|
BEGIN { |
|
7
|
1
|
|
|
1
|
|
34
|
$Data::Conveyor::Exception::Container::VERSION = '1.103130'; |
|
8
|
|
|
|
|
|
|
} |
|
9
|
|
|
|
|
|
|
# ABSTRACT: Stage-based conveyor-belt-like ticket handling system |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
# implements a container object. |
|
12
|
1
|
|
|
1
|
|
6
|
use Data::Miscellany qw/set_push flex_grep/; |
|
|
1
|
|
|
|
|
9
|
|
|
|
1
|
|
|
|
|
66
|
|
|
13
|
1
|
|
|
1
|
|
6
|
use parent 'Class::Scaffold::Exception::Container'; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
9
|
|
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
sub get_disruptive_items { |
|
16
|
11
|
|
|
11
|
1
|
17
|
my ($self, $ticket) = @_; |
|
17
|
|
|
|
|
|
|
return |
|
18
|
11
|
|
0
|
|
|
40
|
grep { !$ticket->ignores_exception($_) && !$_->is_optional } $self->items; |
|
|
0
|
|
|
|
|
0
|
|
|
19
|
|
|
|
|
|
|
} |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# determines the overall rc of the item's exceptions |
|
22
|
|
|
|
|
|
|
sub rc { |
|
23
|
5
|
|
|
5
|
1
|
322
|
my ($self, $ticket, $payload_item) = @_; |
|
24
|
5
|
|
|
|
|
33
|
my $handler = $self->delegate->make_obj('exception_handler'); |
|
25
|
5
|
|
|
|
|
2826
|
my $rc = |
|
26
|
|
|
|
|
|
|
$self->delegate->make_obj('value_ticket_rc', $self->delegate->RC_OK); |
|
27
|
|
|
|
|
|
|
$rc += $handler->rc_for_exception_class($_, $payload_item) |
|
28
|
5
|
|
|
|
|
520
|
for $self->get_disruptive_items($ticket); |
|
29
|
5
|
|
|
|
|
1048
|
$rc; |
|
30
|
|
|
|
|
|
|
} |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# determines the overall status of the item's exceptions |
|
33
|
|
|
|
|
|
|
sub status { |
|
34
|
6
|
|
|
6
|
1
|
63
|
my ($self, $ticket, $payload_item) = @_; |
|
35
|
6
|
|
|
|
|
17
|
my $handler = $self->delegate->make_obj('exception_handler'); |
|
36
|
6
|
|
|
|
|
447
|
my $status = |
|
37
|
|
|
|
|
|
|
$self->delegate->make_obj('value_ticket_status', |
|
38
|
|
|
|
|
|
|
$self->delegate->TS_RUNNING); |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
# Add the status only for exceptions that have an rc that's equal to the |
|
41
|
|
|
|
|
|
|
# ticket's rc -- assuming the ticket's rc has been calculated before, of |
|
42
|
|
|
|
|
|
|
# course. For an explanation, assume the following situation: |
|
43
|
|
|
|
|
|
|
# |
|
44
|
|
|
|
|
|
|
# A ticket has recorded two exceptions: One with RC_OK and TS_HOLD, the |
|
45
|
|
|
|
|
|
|
# other with RC_ERROR and TS_RUNNING. If we just added rc's and stati |
|
46
|
|
|
|
|
|
|
# independently of each other, we'd end up with RC_ERROR and TS_HOLD. This |
|
47
|
|
|
|
|
|
|
# is not what we want. The ticket should go on hold -- for manual |
|
48
|
|
|
|
|
|
|
# inspection -- only if there weren't more serious issues. After all, we |
|
49
|
|
|
|
|
|
|
# don't want to waste a person's time only to later declare that the |
|
50
|
|
|
|
|
|
|
# ticket has serious problems anyway and to abort processing. |
|
51
|
|
|
|
|
|
|
# |
|
52
|
|
|
|
|
|
|
# What we want to end up with in the above situation is RC_ERROR and |
|
53
|
|
|
|
|
|
|
# TS_RUNNING so that the ticket is aborted. We do this by applying the |
|
54
|
|
|
|
|
|
|
# stati of only those exceptions that caused the ticket's overall rc. |
|
55
|
|
|
|
|
|
|
# |
|
56
|
|
|
|
|
|
|
# In our example, that's the exception that caused the RC_ERROR. Since |
|
57
|
|
|
|
|
|
|
# that exception has TS_RUNNING, that's the status we end up with. Which |
|
58
|
|
|
|
|
|
|
# is nice. |
|
59
|
|
|
|
|
|
|
$status += $handler->status_for_exception_class($_, $payload_item) |
|
60
|
6
|
|
|
|
|
631
|
for $self->filter_exceptions_by_rc($ticket, $ticket->rc); |
|
61
|
6
|
|
|
|
|
82
|
$status; |
|
62
|
|
|
|
|
|
|
} |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub filter_exceptions_by_rc { |
|
65
|
6
|
|
|
6
|
1
|
189
|
my ($self, $ticket, @filter) = @_; |
|
66
|
6
|
|
|
|
|
19
|
my $handler = $self->delegate->make_obj('exception_handler'); |
|
67
|
6
|
|
|
|
|
420
|
grep { flex_grep($handler->rc_for_exception_class($_), @filter) } |
|
|
0
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
$self->get_disruptive_items($ticket); |
|
69
|
|
|
|
|
|
|
} |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
sub filter_exceptions_by_status { |
|
72
|
0
|
|
|
0
|
1
|
|
my ($self, $ticket, @filter) = @_; |
|
73
|
0
|
|
|
|
|
|
my $handler = $self->delegate->make_obj('exception_handler'); |
|
74
|
0
|
|
|
|
|
|
grep { flex_grep($handler->status_for_exception_class($_), @filter) } |
|
|
0
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
$self->get_disruptive_items($ticket); |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
# Transactions ask their item (which asks their exception container) whether |
|
79
|
|
|
|
|
|
|
# it has problematic exceptions that should cause the transaction's status to |
|
80
|
|
|
|
|
|
|
# be set to $self->delegate->TXS_ERROR. See Data::Conveyor::Ticket::Transaction. |
|
81
|
|
|
|
|
|
|
# |
|
82
|
|
|
|
|
|
|
# Ordinarily, exceptions with an rc of RC_ERROR or RC_INTERNAL_ERROR are |
|
83
|
|
|
|
|
|
|
# considered problematic. The exception's status can also have an effect on |
|
84
|
|
|
|
|
|
|
# the tx's status. For example, in NICAT, an ::Onwait exception will have |
|
85
|
|
|
|
|
|
|
# RC_OK and TS_HOLD, which should leave the tx on TXS_RUNNING in non-mass |
|
86
|
|
|
|
|
|
|
# tickets (i.e., the legal department will decide whether to shift the ticket |
|
87
|
|
|
|
|
|
|
# to the delegation stage). Same for RC_MANUAL. I.e., set the tx status only |
|
88
|
|
|
|
|
|
|
# to TXS_ERROR if the exception indicates an RC_ERROR or an RC_INTERNAL_ERROR. |
|
89
|
|
|
|
|
|
|
# In mass tickets, we don't want to hold up the ticket - just set the |
|
90
|
|
|
|
|
|
|
# corresponding exception to TXS_ERROR - but only for optional exceptions. |
|
91
|
|
|
|
|
|
|
sub has_problematic_exceptions { |
|
92
|
0
|
|
|
0
|
1
|
|
my ($self, $ticket, $payload_item) = @_; |
|
93
|
0
|
|
|
|
|
|
my $handler = $self->delegate->make_obj('exception_handler'); |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# Don't use get_disruptive_items() because that would weed out exceptions |
|
96
|
|
|
|
|
|
|
# marked with is_optional() as well. But even optional exceptions should |
|
97
|
|
|
|
|
|
|
# cause a TXS_ERROR, if they aren't RC_OK. |
|
98
|
0
|
|
|
|
|
|
my @exceptions = |
|
99
|
0
|
|
|
|
|
|
grep { !$ticket->ignores_exception($_) } $self->items; |
|
100
|
0
|
|
|
|
|
|
for my $exception (@exceptions) { |
|
101
|
0
|
|
|
|
|
|
my $rc = $handler->rc_for_exception_class($exception, $payload_item); |
|
102
|
0
|
|
|
|
|
|
my $status = $handler->status_for_exception_class($exception); |
|
103
|
0
|
0
|
0
|
|
|
|
return 1 |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
104
|
|
|
|
|
|
|
if $rc eq $self->delegate->RC_ERROR |
|
105
|
|
|
|
|
|
|
|| $rc eq $self->delegate->RC_INTERNAL_ERROR |
|
106
|
|
|
|
|
|
|
|| !( |
|
107
|
|
|
|
|
|
|
$status eq $self->delegate->TS_RUNNING |
|
108
|
|
|
|
|
|
|
|| $status eq $self->delegate->TS_HOLD |
|
109
|
|
|
|
|
|
|
|| $status eq $self->delegate->TS_PENDING |
|
110
|
|
|
|
|
|
|
); |
|
111
|
|
|
|
|
|
|
} |
|
112
|
0
|
|
|
|
|
|
return 0; |
|
113
|
|
|
|
|
|
|
} |
|
114
|
|
|
|
|
|
|
1; |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
__END__ |