File: 08_quick_reuse.t

package info (click to toggle)
libpoe-component-client-keepalive-perl 0.2720-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 276 kB
  • sloc: perl: 2,465; makefile: 2
file content (153 lines) | stat: -rw-r--r-- 3,296 bytes parent folder | download | duplicates (3)
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;