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__ |