File Coverage

blib/lib/IO/Async/Protocol.pm
Criterion Covered Total %
statement 53 57 92.9
branch 15 24 62.5
condition n/a
subroutine 12 13 92.3
pod 5 6 83.3
total 85 100 85.0


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2011 -- leonerd@leonerd.org.uk
5              
6             package IO::Async::Protocol;
7              
8 4     4   1642 use strict;
  4         10  
  4         123  
9 4     4   21 use warnings;
  4         6  
  4         185  
10              
11             our $VERSION = '0.801';
12              
13 4     4   24 use base qw( IO::Async::Notifier );
  4         9  
  4         939  
14              
15 4     4   31 use Carp;
  4         8  
  4         1406  
16              
17             =head1 NAME
18              
19             C - base class for transport-based protocols
20              
21             =head1 DESCRIPTION
22              
23             This subclass of L provides storage for a
24             L object, to act as a transport for some protocol. It
25             contains an instance of the transport object, which it adds as a child
26             notifier, allowing a level of independence from the actual transport being
27             used. For example, a stream may actually be an L to
28             allow the protocol to be used over SSL.
29              
30             This class is not intended to be used directly, instead, see one of the
31             subclasses
32              
33             =over 4
34              
35             =item L - base class for stream-based protocols
36              
37             =back
38              
39             =cut
40              
41             =head1 EVENTS
42              
43             The following events are invoked, either using subclass methods or CODE
44             references in parameters:
45              
46             =head2 on_closed
47              
48             Optional. Invoked when the transport handle becomes closed.
49              
50             =cut
51              
52             =head1 PARAMETERS
53              
54             The following named parameters may be passed to C or C:
55              
56             =head2 transport => IO::Async::Handle
57              
58             The L to delegate communications to.
59              
60             =head2 on_closed => CODE
61              
62             CODE reference for the C event.
63              
64             When a new C object is given, it will be configured by calling the
65             C method, then added as a child notifier. If a different
66             transport object was already configured, this will first be removed and
67             deconfigured using the C.
68              
69             =cut
70              
71             sub configure
72             {
73 17     17 1 1372 my $self = shift;
74 17         67 my %params = @_;
75              
76 17         35 for (qw( on_closed )) {
77 17 100       60 $self->{$_} = delete $params{$_} if exists $params{$_};
78             }
79              
80 17 100       44 if( exists $params{transport} ) {
81 10         19 my $transport = delete $params{transport};
82              
83 10 100       44 if( $self->{transport} ) {
84 3         22 $self->remove_child( $self->transport );
85              
86 3         9 $self->teardown_transport( $self->transport );
87             }
88              
89 10         18 $self->{transport} = $transport;
90              
91 10 100       33 if( $transport ) {
92 8         49 $self->setup_transport( $self->transport );
93              
94 8         21 $self->add_child( $self->transport );
95             }
96             }
97              
98 17         55 $self->SUPER::configure( %params );
99             }
100              
101             =head1 METHODS
102              
103             =cut
104              
105             =head2 transport
106              
107             $transport = $protocol->transport
108              
109             Returns the stored transport object
110              
111             =cut
112              
113             sub transport
114             {
115 30     30 1 266 my $self = shift;
116 30         151 return $self->{transport};
117             }
118              
119             =head2 connect
120              
121             $protocol->connect( %args )
122              
123             Sets up a connection to a peer, and configures the underlying C for
124             the Protocol.
125              
126             Takes the following named arguments:
127              
128             =over 8
129              
130             =item socktype => STRING or INT
131              
132             Required. Identifies the socket type, and the type of continuation that will
133             be used. If this value is C<"stream"> or C then C
134             continuation will be used; otherwise C will be used.
135              
136             =item on_connected => CODE
137              
138             Optional. If supplied, will be invoked once the connection has been
139             established.
140              
141             $on_connected->( $protocol )
142              
143             =item transport => IO::Async::Handle
144              
145             Optional. If this is provided, it will immediately be configured as the
146             transport (by calling C), and the C callback will be
147             invoked. This is provided as a convenient shortcut.
148              
149             =back
150              
151             Other arguments will be passed to the underlying L C
152             call.
153              
154             =cut
155              
156             sub connect
157             {
158 1     1 1 2 my $self = shift;
159 1         8 my %args = @_;
160              
161 1         3 my $on_connected = delete $args{on_connected};
162              
163 1 50       4 if( my $transport = $args{transport} ) {
164 0         0 $self->configure( transport => $transport );
165              
166 0 0       0 $on_connected->( $self ) if $on_connected;
167              
168 0         0 return;
169             }
170              
171 1 50       4 my $socktype = $args{socktype} or croak "Expected socktype";
172              
173 1 50       2 my $on_transport = do {
174 4     4   34 no warnings 'numeric';
  4         17  
  4         1502  
175 1 50       6 $socktype eq "stream" || $socktype == Socket::SOCK_STREAM()
176             } ? "on_stream" : "on_socket";
177              
178 1 50       5 my $loop = $self->loop or croak "Cannot ->connect a ".ref($self)." that is not in a Loop";
179              
180             $loop->connect(
181             %args,
182             socktype => "stream",
183              
184             $on_transport => sub {
185 1     1   124 my ( $transport ) = @_;
186              
187 1         6 $self->configure( transport => $transport );
188              
189 1 50       6 $on_connected->( $self ) if $on_connected;
190             },
191 1         13 );
192             }
193              
194             =head1 TRANSPORT DELEGATION
195              
196             The following methods are delegated to the transport object
197              
198             close
199              
200             =cut
201              
202 0     0 0 0 sub close { shift->transport->close }
203              
204             =head1 SUBCLASS METHODS
205              
206             C is a base class provided so that specific subclasses of
207             it provide more specific behaviour. The base class provides a number of
208             methods that subclasses may wish to override.
209              
210             If a subclass implements any of these, be sure to invoke the superclass method
211             at some point within the code.
212              
213             =cut
214              
215             =head2 setup_transport
216              
217             $protocol->setup_transport( $transport )
218              
219             Called by C when a new C object is given, this method
220             should perform whatever setup is required to wire the new transport object
221             into the protocol object; typically by setting up event handlers.
222              
223             =cut
224              
225             sub setup_transport
226             {
227 8     8 1 39 my $self = shift;
228 8         17 my ( $transport ) = @_;
229              
230             $transport->configure(
231             on_closed => $self->_capture_weakself( sub {
232 2 50   2   7 my $self = shift or return;
233 2         4 my ( $transport ) = @_;
234              
235 2         11 $self->maybe_invoke_event( on_closed => );
236              
237 2         13 $self->configure( transport => undef );
238 8         69 } ),
239             );
240             }
241              
242             =head2 teardown_transport
243              
244             $protocol->teardown_transport( $transport )
245              
246             The reverse of C; called by C when a previously
247             set-up transport object is about to be replaced.
248              
249             =cut
250              
251             sub teardown_transport
252             {
253 3     3 1 20 my $self = shift;
254 3         6 my ( $transport ) = @_;
255              
256 3         17 $transport->configure(
257             on_closed => undef,
258             );
259             }
260              
261             =head1 AUTHOR
262              
263             Paul Evans
264              
265             =cut
266              
267             0x55AA;