File Coverage

blib/lib/Sprocket/Plugin.pm
Criterion Covered Total %
statement 59 122 48.3
branch 7 32 21.8
condition 4 9 44.4
subroutine 17 32 53.1
pod 17 20 85.0
total 104 215 48.3


line stmt bran cond sub pod time code
1             package Sprocket::Plugin;
2              
3 5     5   28 use Class::Accessor::Fast;
  5         9  
  5         36  
4 5     5   143 use base qw(Class::Accessor::Fast);
  5         20  
  5         387  
5 5     5   26 use Scalar::Util qw( weaken blessed );
  5         12  
  5         283  
6 5     5   24 use POE;
  5         9  
  5         37  
7 5     5   1396 use Sprocket;
  5         40  
  5         30  
8 5     5   2640 use Sprocket::Local;
  5         12  
  5         30  
9 5     5   33 use Errno qw( EADDRINUSE );
  5         12  
  5         493  
10              
11             __PACKAGE__->mk_accessors( qw( uuid _uuid name parent_id ID ) );
12              
13 5     5   29 use overload '""' => sub { shift->ID() };
  5     10   9  
  5         59  
  10         51  
14              
15 5     5   285 use strict;
  5         8  
  5         128  
16 5     5   21 use warnings;
  5         8  
  5         7255  
17              
18             # Sprocket::Spread import will replace this
19             # when imported on demand
20             our $sprocket_spread;
21              
22             our %plugin_event_list = map { $_ => 1 } qw(
23             local_accept
24             local_connected
25             local_receive
26             local_disconnected
27             local_time_out
28             local_error
29              
30             remote_accept
31             remote_connected
32             remote_receive
33             remote_disconnected
34             remote_connect_error
35             remote_time_out
36              
37             plugin_start_aio
38             add_plugin
39             );
40              
41             our %plugin_event_discon = map { $_ => 1 } qw(
42             local_disconnected
43              
44             remote_disconnected
45             remote_connect_error
46             );
47              
48             sub new {
49 10     10 1 254 my $class = shift;
50            
51 10   33     54 my $self = bless( {
52             __conlist__ => {},
53             &adjust_params,
54             }, ref $class || $class );
55              
56             # unique uuid, different for each instance
57 10         44 $self->uuid( new_uuid() );
58            
59 10         1012421 $self->ID( $class.'/'.$self->uuid );
60            
61             # uuid based off of the plugin's ref
62 10         289 $self->_uuid( gen_uuid( $self ) );
63              
64 10         163 $sprocket->add_plugin( $self );
65            
66 10         96 return $self;
67             }
68              
69             sub handle_event {
70 61     61 0 110 my ( $self, $event ) = ( shift, shift );
71            
72 61 100 66     336 delete $self->{__conlist__}->{ $_[ 1 ]->ID }
73             if ( $self->{__conlist__} && exists( $plugin_event_discon{ $event } ) );
74            
75 61 100       356 if ( $self->can( $event ) ) {
76 40         172 $self->$event( @_ );
77             } else {
78 21 50 33     89 $self->_log( v => $self->{log_unhandled_events}, msg => "unhandled plugin event: $event" )
79             if ( $self->{log_unhandled_events} && !exists( $plugin_event_list{ $event } ) );
80             }
81            
82 61         2856 return 1;
83             }
84              
85             sub _log {
86 0     0   0 $poe_kernel->call( shift->parent_id => _log => ( call => ( caller(1) )[ 3 ], @_ ) );
87 0         0 return;
88             }
89              
90             # ==========================================
91             # Events
92             # ==========================================
93              
94             sub local_accept {
95 4     4 1 9 my ( $self, $server, $con, $socket ) = @_;
96 4 50       35 if ( $server->shutting_down ) {
97 0         0 $con->reject();
98             } else {
99 4         44 $con->accept();
100             }
101 4         29 return;
102             }
103              
104             sub local_connected {
105 0     0 1 0 my ( $self, $server, $con, $socket ) = @_;
106 0         0 $server->_log( v => 4, msg => 'Rejecting connection because plugin:'
107             .$self.' did not define a local_connected event' );
108 0         0 $con->reject();
109 0         0 return;
110             }
111              
112             sub local_error {
113 0     0 1 0 my ( $self, $server, $operation, $errnum, $errstr ) = @_;
114             # note that this has no $con, it's a server wheel error
115 0 0       0 $server->shutdown() if ( $errnum == EADDRINUSE );
116 0         0 return;
117             }
118              
119             sub local_time_out {
120 0     0 1 0 my ( $self, $server, $con, $time ) = @_;
121 0         0 $server->_log( v => 4, msg => 'Timeout for connection ' );
122 0         0 $con->close();
123 0         0 return;
124             }
125              
126             sub local_shutdown {
127 0     0 1 0 my ( $self, $server, $con ) = @_;
128 0         0 $server->_log( v => 4, msg => 'Closing connection, shutting down' );
129 0         0 $con->close( 1 );
130 0         0 return;
131             }
132              
133             sub remote_connected {
134 0     0 1 0 my ( $self, $client, $con, $socket ) = @_;
135 0         0 $client->_log( v => 4, msg => 'Rejecting connection because plugin:'
136             .$self.' did not define a remote_connected event' );
137 0         0 $con->reject();
138 0         0 return;
139             }
140              
141             sub remote_accept {
142 4     4 1 20 my ( $self, $client, $con, $socket ) = @_;
143             # XXX shutting_down?
144 4         17 $con->accept();
145 4         25 return;
146             }
147              
148             sub remote_disconnected {
149 0     0 1 0 my ( $self, $client, $con ) = @_;
150 0         0 $con->close();
151 0         0 return;
152             }
153              
154             sub remote_connect_error {
155 0     0 1 0 my ( $self, $client, $con, $res_err, $res_obj ) = @_;
156 0         0 $con->close();
157 0         0 return;
158             }
159              
160             sub remote_time_out {
161 0     0 1 0 my ( $self, $client, $con, $time ) = @_;
162 0         0 $client->_log( v => 4, msg => 'Timeout for connection' );
163 0         0 $con->close();
164 0         0 return;
165             }
166              
167             sub remote_shutdown {
168 1     1 1 2 my ( $self, $client, $con ) = @_;
169 1         4 $client->_log( v => 4, msg => 'Closing connection, shutting down' );
170 1         5 $con->close( 1 );
171 1         109 return;
172             }
173              
174             # ==========================================
175             # Methods
176             # ==========================================
177              
178             sub get_plugin_connection {
179 0     0 0 0 my ( $self, $server, $id ) = @_;
180              
181             # Sprocket::Local singleton
182 0         0 return $sprocket_local->get_connection( $server, $id );
183             }
184              
185             sub take_connection {
186 8     8 1 70 my ( $self, $con ) = @_;
187            
188 8 50       52 $self->{__conlist__}->{ $con->ID } = 1
189             if ( $self->{__conlist__} );
190            
191 8         57 $con->plugin( $self->uuid );
192 8         73 return;
193             }
194              
195             sub release_connection {
196 0     0 1   my ( $self, $con ) = @_;
197            
198 0 0         delete $self->{__conlist__}->{ $con->ID }
199             if ( $self->{__conlist__} );
200            
201 0           $con->plugin( undef );
202 0           return;
203             }
204              
205             sub spread_subscribe {
206 0     0 1   my ( $self, $groups ) = @_;
207              
208 0 0         if ( !defined( $sprocket_spread ) ) {
209             # XXX is there a better way?
210 0           require Sprocket::Spread;
211 0           import Sprocket::Spread;
212             }
213            
214 0 0         $groups = [ $groups ] unless ( ref $groups );
215              
216 0           return $sprocket_spread->plugin_subscribe( $self, $groups );
217             }
218              
219             sub spread_unsubscribe {
220 0     0 1   my ( $self, $groups ) = @_;
221              
222 0 0         if ( !defined( $sprocket_spread ) ) {
223             # XXX is there a better way?
224 0           require Sprocket::Spread;
225 0           import Sprocket::Spread;
226             }
227 0 0         $groups = [ $groups ] unless ( ref $groups );
228              
229 0           return $sprocket_spread->plugin_unsubscribe( $self, $groups );
230             }
231              
232             sub spread_publish {
233 0     0 1   my $self = shift;
234 0           my $groups = shift;
235              
236 0 0         if ( !defined( $sprocket_spread ) ) {
237             # XXX is there a better way?
238 0           require Sprocket::Spread;
239 0           import Sprocket::Spread;
240             }
241            
242 0 0         $groups = [ $groups ] unless ( ref $groups );
243              
244 0           return $sprocket_spread->plugin_publish( $self, $groups, @_ );
245             }
246              
247             sub con_list {
248 0     0 0   my $self = shift;
249            
250 0 0         if ( $self->{__conlist__} ) {
251 0           my @ids = keys %{ $self->{__conlist__} };
  0            
252 0 0         return wantarray ? @ids : \@ids;
253             }
254              
255 0 0         return wantarray ? () : [];
256             }
257              
258             *con_id_list = *con_list;
259              
260             1;
261              
262             __END__