File Coverage

blib/lib/SRS/EPP/Session/BackendQ.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1              
2             package SRS::EPP::Session::BackendQ;
3              
4 2     2   19233 use SRS::EPP::SRSRequest;
  0            
  0            
5             use SRS::EPP::SRSResponse;
6             use SRS::EPP::Command;
7              
8             use Moose;
9             use MooseX::Method::Signatures;
10              
11             has 'queue' =>
12             is => "ro",
13             isa => "ArrayRef[ArrayRef[SRS::EPP::SRSRequest]]",
14             default => sub { [] },
15             ;
16              
17             has 'owner' =>
18             is => "ro",
19             isa => "ArrayRef[SRS::EPP::Command]",
20             default => sub { [] },
21             ;
22              
23             has 'responses' =>
24             is => "ro",
25             isa => "ArrayRef[ArrayRef[SRS::EPP::SRSResponse]]",
26             default => sub { [] },
27             ;
28              
29             has 'sent' =>
30             is => "rw",
31             isa => "Int",
32             default => 0,
33             ;
34              
35             has 'session' =>
36             is => "ro",
37             isa => "SRS::EPP::Session",
38             ;
39              
40             # add a response corresponding to a request
41             method queue_backend_request( SRS::EPP::Command $cmd, SRS::EPP::SRSRequest @rq ) {
42             push @{ $self->queue }, \@rq;
43             push @{ $self->responses }, [];
44             push @{ $self->owner }, $cmd;
45             }
46              
47             use List::Util qw(sum);
48              
49             method queue_size() {
50             sum 0, map { scalar @$_ } @{$self->queue};
51             }
52             method queue_flat() {
53             map { @$_ } @{$self->queue};
54             }
55              
56             # get the next N backend messages to be sent; marks them as sent
57             method backend_next( Int $how_many = 1 ) {
58             return unless $how_many;
59             my $sent = $self->sent;
60             my $waiting = $self->queue_size - $sent;
61             $how_many = $waiting if $how_many > $waiting;
62             my @rv = ($self->queue_flat)[ $sent .. $sent + $how_many - 1 ];
63             $self->sent($sent + @rv);
64             return @rv;
65             }
66              
67             method backend_pending() {
68             my $sent = $self->sent;
69             my $waiting = $self->queue_size - $sent;
70             return $waiting;
71             }
72              
73             # add a response corresponding to a request - must be in order as
74             # there is no other way to correlate read-only responses with their
75             # requests (no client_tx_id in SRS requests)
76             method add_backend_response( SRS::EPP::SRSRequest $request, SRS::EPP::SRSResponse $response )
77             {
78             my $rq_a = $self->queue->[0];
79             my $rs_a = $self->responses->[0];
80             for ( my $i = 0; $i <= $#$rq_a; $i++ ) {
81             if ( $rq_a->[$i] == $request ) {
82             $rs_a->[$i] = $response;
83             }
84             }
85             }
86              
87             method backend_response_ready() {
88             my $rq_a = $self->queue->[0]
89             or return;
90             my $rs_a = $self->responses->[0];
91             @$rq_a == @$rs_a;
92             }
93              
94             method dequeue_backend_response() {
95             if ( $self->backend_response_ready ) {
96             my $rq_a = shift @{ $self->queue };
97             my $owner = shift @{ $self->owner };
98             my $rs_a = shift @{ $self->responses };
99             my $sent = $self->sent;
100             $sent -= scalar @$rq_a;
101             if ( $sent < 0 ) {
102             warn "Bug: sent < 0 ?";
103             $sent = 0;
104             }
105             $self->sent($sent);
106              
107             if ( wantarray ) {
108             ($owner, @$rs_a);
109             }
110             else {
111             $owner->notify(@$rs_a);
112             }
113             }
114             else {
115             ();
116             }
117             }
118              
119             1;
120              
121             __END__
122              
123             =head1 NAME
124              
125             SRS::EPP::Session::BackendQ - manage tx queue for back-end processing
126              
127             =head1 SYNOPSIS
128              
129             my $q = SRS::EPP::Session::BackendQ->new( session => $session );
130              
131             # put requests on queue
132             $q->queue_backend_request( $epp_command, @srs_requests );
133              
134             # pull up to 6 requests off queue for processing
135             my @rq = $q->backend_next( 6 );
136              
137             # put responses in, one by one.
138             for (1..6) {
139             $q->add_backend_response( $rq[$i], $rs[$i] );
140             }
141              
142             # if a message has had all its requests answered, it can be dequeued
143             ($epp_command, @srs_responses)
144             = $q->dequeue_backend_response();
145              
146             =head1 DESCRIPTION
147              
148             This class implements a simple FIFO queue, but with small
149             customizations to operation to suit the use case of the SRS EPP Proxy
150             tracking the requests it sends to the back-end.
151              
152             =head1 SEE ALSO
153              
154             L<SRS::EPP::Session>
155              
156             =head1 AUTHOR AND LICENCE
157              
158             Development commissioned by NZ Registry Services, and carried out by
159             Catalyst IT - L<http://www.catalyst.net.nz/>
160              
161             Copyright 2009, 2010, NZ Registry Services. This module is licensed
162             under the Artistic License v2.0, which permits relicensing under other
163             Free Software licenses.
164              
165             =cut
166              
167              
168             # Local Variables:
169             # mode:cperl
170             # indent-tabs-mode: t
171             # cperl-continued-statement-offset: 8
172             # cperl-brace-offset: 0
173             # cperl-close-paren-offset: 0
174             # cperl-continued-brace-offset: 0
175             # cperl-continued-statement-offset: 8
176             # cperl-extra-newline-before-brace: nil
177             # cperl-indent-level: 8
178             # cperl-indent-parens-as-block: t
179             # cperl-indent-wrt-brace: nil
180             # cperl-label-offset: -8
181             # cperl-merge-trailing-else: t
182             # End: