package LWP::ConnCache;
use strict;
use vars qw($VERSION $DEBUG);
$VERSION = "5.810";
sub new {
my($class, %cnf) = @_;
my $total_capacity = delete $cnf{total_capacity};
$total_capacity = 1 unless defined $total_capacity;
if (%cnf && $^W) {
require Carp;
Carp::carp("Unrecognised options: @{[sort keys %cnf]}")
}
my $self = bless { cc_conns => [] }, $class;
$self->total_capacity($total_capacity);
$self;
}
sub deposit {
my($self, $type, $key, $conn) = @_;
push(@{$self->{cc_conns}}, [$conn, $type, $key, time]);
$self->enforce_limits($type);
return;
}
sub withdraw {
my($self, $type, $key) = @_;
my $conns = $self->{cc_conns};
for my $i (0 .. @$conns - 1) {
my $c = $conns->[$i];
next unless $c->[1] eq $type && $c->[2] eq $key;
splice(@$conns, $i, 1); # remove it
return $c->[0];
}
return undef;
}
sub total_capacity {
my $self = shift;
my $old = $self->{cc_limit_total};
if (@_) {
$self->{cc_limit_total} = shift;
$self->enforce_limits;
}
$old;
}
sub capacity {
my $self = shift;
my $type = shift;
my $old = $self->{cc_limit}{$type};
if (@_) {
$self->{cc_limit}{$type} = shift;
$self->enforce_limits($type);
}
$old;
}
sub enforce_limits {
my($self, $type) = @_;
my $conns = $self->{cc_conns};
my @types = $type ? ($type) : ($self->get_types);
for $type (@types) {
next unless $self->{cc_limit};
my $limit = $self->{cc_limit}{$type};
next unless defined $limit;
for my $i (reverse 0 .. @$conns - 1) {
next unless $conns->[$i][1] eq $type;
if (--$limit < 0) {
$self->dropping(splice(@$conns, $i, 1), "$type capacity exceeded");
}
}
}
if (defined(my $total = $self->{cc_limit_total})) {
while (@$conns > $total) {
$self->dropping(shift(@$conns), "Total capacity exceeded");
}
}
}
sub dropping {
my($self, $c, $reason) = @_;
print "DROPPING @$c [$reason]\n" if $DEBUG;
}
sub drop {
my($self, $checker, $reason) = @_;
if (ref($checker) ne "CODE") {
=1= |