1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
#!/usr/bin/perl
# Test rapid connection reuse. Sets the maximum overall connections
# to a low number. Allocate up to the maximum. Reuse one of the
# connections, and allocate a completely different connection. The
# allocation shuld be deferred, and one of the free sockets in the
# keep-alive pool should be discarded to make room for it.
use warnings;
use strict;
use lib qw(./mylib ../mylib);
use Test::More tests => 7;
sub POE::Kernel::ASSERT_DEFAULT () { 1 }
use POE;
use POE::Component::Client::Keepalive;
use POE::Component::Resolver;
use Socket qw(AF_INET);
use TestServer;
my $port_a = TestServer->spawn(0);
my $port_b = TestServer->spawn(0);
POE::Session->create(
inline_states => {
_child => sub { },
_start => \&start,
_stop => sub { },
got_another_conn => \&got_another_conn,
got_conn => \&got_conn,
got_error => \&got_error,
}
);
sub start {
my $heap = $_[HEAP];
$heap->{cm} = POE::Component::Client::Keepalive->new(
max_open => 2,
resolver => POE::Component::Resolver->new(af_order => [ AF_INET ]),
);
$heap->{conn_count} = 0;
{
$heap->{cm}->allocate(
scheme => "http",
addr => "localhost",
port => $port_a,
event => "got_conn",
context => "first",
);
}
{
$heap->{cm}->allocate(
scheme => "http",
addr => "localhost",
port => $port_a,
event => "got_conn",
context => "second",
);
}
}
sub got_conn {
my ($heap, $response) = @_[HEAP, ARG0];
my $conn = delete $response->{connection};
my $which = $response->{context};
if (defined $conn) {
pass "$which request established asynchronously";
}
else {
fail(
"$which request $response->{function} error $response->{error_num}: " .
$response->{error_str}
);
}
ok(!defined($response->{from_cache}), "$which connection request deferred");
$conn = undef;
return unless ++$heap->{conn_count} == 2;
# Re-allocate one of the connections.
$heap->{cm}->allocate(
scheme => "http",
addr => "localhost",
port => $port_a,
event => "got_another_conn",
context => "third",
);
$heap->{cm}->allocate(
scheme => "http",
addr => "localhost",
port => $port_b,
event => "got_another_conn",
context => "fourth",
);
}
sub got_another_conn {
my ($heap, $response) = @_[HEAP, ARG0];
# Deleting here to avoid a copy of the connection in %$response.
my $conn = delete $response->{connection};
my $which = $response->{context};
if ($which eq 'third') {
is(
$response->{from_cache}, 'immediate',
"$which connection request honored from pool"
);
return;
}
if ($which eq 'fourth') {
ok(
!defined ($response->{from_cache}),
"$which connection request honored from pool"
);
if (defined $conn) {
pass "$which request established asynchronously";
}
else {
fail(
"$which request $response->{function} error $response->{error_num}: " .
$response->{error_str}
);
}
# Free the connection first.
$conn = undef;
TestServer->shutdown();
$heap->{cm}->shutdown();
return;
}
die;
}
POE::Kernel->run();
exit;
|