File Coverage

inc/TestServer.pm
Criterion Covered Total %
statement 76 78 97.4
branch 8 10 80.0
condition n/a
subroutine 15 16 93.7
pod 0 4 0.0
total 99 108 91.6


line stmt bran cond sub pod time code
1             package TestServer;
2             # test server for proxy test - Andrew V. Purshottam
3             # accepts lines of form count: text
4             # to do:
5             # (done) fix same error as in proxy! the shutdown state variable is server wide,
6             # not per client connectection! Ok, fixed it, now shutdown is in heap,
7             # so per client connection. This was easy, because the PoCo::Server::TCP
8             # had all the state already in the per connection session. I am begining to
9             # appreciate POE...
10            
11 1     1   58410 use warnings;
  1         2  
  1         60  
12 1     1   6 use strict;
  1         2  
  1         31  
13 1     1   7 use diagnostics;
  1         2  
  1         7  
14            
15             # sub POE::Kernel::ASSERT_DEFAULT () { 1 }
16 1     1   55 use POE;
  1         8  
  1         10  
17 1     1   657 use POE::Filter::Stream;
  1         2  
  1         36  
18 1     1   6 use POE::Filter::Line;
  1         2  
  1         47  
19 1     1   7 use POE qw(Component::Server::TCP);
  1         2  
  1         18  
20 1     1   557 use POE::Component::Proxy::TCP::PoeDebug;
  1         13  
  1         266  
21            
22 1     1   7 use fields qw(port );
  1         1  
  1         11  
23            
24             sub new {
25 1     1 0 356 my TestServer $self = shift;
26 1 50       5 unless (ref $self) {
27 1         6 $self = fields::new($self);
28             }
29            
30             # private instance variables init...
31            
32             # Extract parameters...
33 1         9981 my %param = @_;
34            
35 1         5 $self->{port} = delete $param{Port};
36 1 50       8 $self->{port} = 8000 unless defined ($self->{port});
37 1         2 my $base_delay = 0;
38             # Create TCP server and start listener session.
39             POE::Component::Server::TCP->new
40             ( Alias => "proxy_test_server",
41             Port => $self->{port},
42             Args => [$self], # so handle_client_connect_to_server gets $self
43             ClientConnected => \&handle_client_connect_to_server,
44             ClientFilter => "POE::Filter::Line",
45             ClientInput => sub {
46 6     6   4204 my ( $kernel, $session, $heap, $input ) = @_[ KERNEL, SESSION, HEAP, ARG0 ];
47 6         26 dbprint(3, "Session ", $session->ID(), " got input: $input");
48 6 100       36 if ($input =~ m/^END/) {
49 2         8 dbprint(2,"TEST SERVER GOT END REQUEST\n");
50 2         5 $heap->{_shutting_down} = 1;
51 2         8 check_for_shutdown();
52             } else {
53 4         20 my ($count, $text) = split /:/, $input;
54 4         621 dbprint(2, "got request count:", $count, " text:", $text);
55 4         29 for (my $i = 0; $i < $count; $i++) {
56 32         126 reply_after_delay($i + $base_delay, "$i:$text:" );
57 32         5446 dbprint(3, "sent $i:$text:");
58             }
59 4         20 $base_delay += $count;
60             }
61             },
62            
63             InlineStates => {send => sub {
64 0     0   0 my ( $heap, $message ) = @_[ HEAP, ARG0 ];
65 0         0 $heap->{client}->put($message);
66             },
67             send_delayed => sub {
68 32     32   32902307 my ( $heap, $message ) = @_[ HEAP, ARG0 ];
69 32         343 $heap->{client}->put($message);
70 32         9445 $heap->{_pending_self_requests}--;
71 32         132 check_for_shutdown();
72            
73             }},
74 1         36 Args => [$self],
75            
76             );
77            
78 1         5870 return $self;
79             }
80            
81            
82             # Called inside per client connection session
83             # sets up $heap->{self} to be the TestServer instance
84             # a pure OO approach to POE where one could subclass
85             # the per connection session and put instance data
86             # there might have been nicer?
87            
88             sub handle_client_connect_to_server {
89 2     2 0 4215 my ( $kernel, $session, $heap, $self ) = @_[ KERNEL, SESSION, HEAP, ARG0 ];
90 2         8 my $session_id = $session->ID;
91 2         11 $heap->{self} = $self;
92 2         5 $heap->{_pending_self_requests} = 0;
93 2         7 $heap->{_shutting_down} = 0;
94            
95 2         9 dbprint(1, "Client connected.");
96             }
97            
98             # hack to support sending lines to the client, and
99             # make sure the client connection session is kept running
100             # until all pending lines have been set.
101             # If we had access to the event queue, we could look
102             # to see if any send events for the per client connection
103             # session were available. Q for POE[tr]s: should this be possible?
104            
105             # reply_after_delay($delay_secs, $text)
106             # does crap to get env without having to pass,
107             # then updates pend and posts a delayed event.
108             sub reply_after_delay {
109 32     32 0 1589 my $delay_secs = shift;
110 32         44 my $text = shift;
111 32         44 my $kernel = $poe_kernel;
112 32         94 my $session = $kernel->get_active_session();
113 32         157 my $heap = $session->get_heap();
114 32         147 my $self = $heap->{self};
115 32         49 $heap->{_pending_self_requests}++;
116 32         875 $kernel->delay_add( "send_delayed", $delay_secs, $text);
117             }
118            
119             # check_for_shutdown() - ask TestServer per client session
120             # if it should shut down.
121             sub check_for_shutdown {
122 34     34 0 67 my $kernel = $poe_kernel;
123 34         203 my $session = $kernel->get_active_session();
124 34         313 my $heap = $session->get_heap();
125 34         221 my $self = $heap->{self};
126 34         728 dbprint(10, "check_for_shutdown: sd:$heap->{_shutting_down} psr:$heap->{_pending_self_requests}");
127 34 100       2380 if ($heap->{_shutting_down}) {
128 28 100       127 if ($heap->{_pending_self_requests}) {
129 26         85 dbprint(10, "can't shut down");
130             } else {
131 2         8 dbprint(1, "test server per client connection session shutting down");
132             # reply_after_delay(1, "END");
133 2         14 $kernel->yield( "shutdown" );
134             }
135             }
136             }
137            
138            
139             1;