1#!/usr/bin/perl 2 3# Test connection reuse. Allocates a connection, frees it, and 4# allocates another. The second allocation should return right away 5# because it is honored from the keep-alive pool. 6 7use warnings; 8use strict; 9use lib qw(./mylib ../mylib); 10use Test::More tests => 6; 11 12sub POE::Kernel::ASSERT_DEFAULT () { 1 } 13 14use POE; 15use POE::Component::Client::Keepalive; 16use POE::Component::Resolver; 17use Socket qw(AF_INET); 18 19use TestServer; 20my $server_port = TestServer->spawn(0); 21 22my $test_server_use_count = 0; 23 24POE::Session->create( 25 inline_states => { 26 _child => sub { }, 27 _start => \&start_with, 28 _stop => sub { }, 29 got_conn => \&got_conn, 30 } 31); 32 33POE::Session->create( 34 inline_states => { 35 _child => sub { }, 36 _start => \&start_without, 37 _stop => sub { }, 38 got_conn => \&got_conn, 39 } 40); 41 42sub start_with { 43 my $heap = $_[HEAP]; 44 45 $_[KERNEL]->alias_set ('WITH'); 46 $heap->{cm} = POE::Component::Client::Keepalive->new( 47 resolver => POE::Component::Resolver->new(af_order => [ AF_INET ]), 48 ); 49 50 $heap->{cm}->allocate( 51 scheme => "http", 52 addr => "localhost", 53 port => $server_port, 54 event => "got_conn", 55 context => "first", 56 ); 57 58 ++$test_server_use_count; 59} 60 61sub start_without { 62 my $heap = $_[HEAP]; 63 64 $_[KERNEL]->alias_set ('WITHOUT'); 65 $heap->{cm} = POE::Component::Client::Keepalive->new( 66 resolver => POE::Component::Resolver->new(af_order => [ AF_INET ]), 67 ); 68 69 $heap->{cm}->allocate( 70 scheme => "http", 71 addr => "localhost", 72 port => $server_port, 73 event => "got_conn", 74 context => "second", 75 ); 76 77 ++$test_server_use_count; 78} 79 80# TODO - I think this callback is polymorphic (first vs. second) 81# bcause it has common code. It's probably cleaner to implement two 82# separate callbacks and some helpers to handle their commonalities. 83 84sub got_conn{ 85 my ($kernel, $heap, $response) = @_[KERNEL, HEAP, ARG0]; 86 87 # The delete() ensures only one copy of the connection exists. 88 my $connection = delete $response->{connection}; 89 my $which = $response->{context}; 90 91 if (defined $connection) { 92 pass "$which request honored asynchronously"; 93 } 94 else { 95 fail( 96 "$which request $response->{function} error $response->{error_num}: " . 97 $response->{error_str} 98 ); 99 } 100 101 ok( 102 (not defined $response->{'from_cache'}), 103 "$which request not from cache" 104 ); 105 106 if ($which eq 'first') { 107 ok(1, "$which request from internal resolver"); 108 } elsif ($which eq 'second') { 109 ok(1, "$which request from external resolver"); 110 } 111 112 TestServer->shutdown() unless --$test_server_use_count; 113 114 # need this so we don't get trace output about our session having 115 # already died 116 $connection = undef; 117 # and this so we can terminate without having to go through the 118 # idle polling period 119 $heap->{cm}->shutdown; 120 # and this so we terminate at all 121 delete $heap->{cm}; 122} 123 124POE::Kernel->run(); 125exit; 126