source: main/trunk/greenstone2/perllib/cpan/LWP/ConnCache.pm@ 27183

Last change on this file since 27183 was 27183, checked in by davidb, 11 years ago

Changing to using installed version of LWP that comes from libwww-perl, which is more self-contained than v6.x

File size: 7.4 KB
Line 
1package LWP::ConnCache;
2
3use strict;
4use vars qw($VERSION $DEBUG);
5
6$VERSION = "5.810";
7
8
9sub new {
10 my($class, %cnf) = @_;
11 my $total_capacity = delete $cnf{total_capacity};
12 $total_capacity = 1 unless defined $total_capacity;
13 if (%cnf && $^W) {
14 require Carp;
15 Carp::carp("Unrecognised options: @{[sort keys %cnf]}")
16 }
17 my $self = bless { cc_conns => [] }, $class;
18 $self->total_capacity($total_capacity);
19 $self;
20}
21
22
23sub deposit {
24 my($self, $type, $key, $conn) = @_;
25 push(@{$self->{cc_conns}}, [$conn, $type, $key, time]);
26 $self->enforce_limits($type);
27 return;
28}
29
30
31sub withdraw {
32 my($self, $type, $key) = @_;
33 my $conns = $self->{cc_conns};
34 for my $i (0 .. @$conns - 1) {
35 my $c = $conns->[$i];
36 next unless $c->[1] eq $type && $c->[2] eq $key;
37 splice(@$conns, $i, 1); # remove it
38 return $c->[0];
39 }
40 return undef;
41}
42
43
44sub total_capacity {
45 my $self = shift;
46 my $old = $self->{cc_limit_total};
47 if (@_) {
48 $self->{cc_limit_total} = shift;
49 $self->enforce_limits;
50 }
51 $old;
52}
53
54
55sub capacity {
56 my $self = shift;
57 my $type = shift;
58 my $old = $self->{cc_limit}{$type};
59 if (@_) {
60 $self->{cc_limit}{$type} = shift;
61 $self->enforce_limits($type);
62 }
63 $old;
64}
65
66
67sub enforce_limits {
68 my($self, $type) = @_;
69 my $conns = $self->{cc_conns};
70
71 my @types = $type ? ($type) : ($self->get_types);
72 for $type (@types) {
73 next unless $self->{cc_limit};
74 my $limit = $self->{cc_limit}{$type};
75 next unless defined $limit;
76 for my $i (reverse 0 .. @$conns - 1) {
77 next unless $conns->[$i][1] eq $type;
78 if (--$limit < 0) {
79 $self->dropping(splice(@$conns, $i, 1), "$type capacity exceeded");
80 }
81 }
82 }
83
84 if (defined(my $total = $self->{cc_limit_total})) {
85 while (@$conns > $total) {
86 $self->dropping(shift(@$conns), "Total capacity exceeded");
87 }
88 }
89}
90
91
92sub dropping {
93 my($self, $c, $reason) = @_;
94 print "DROPPING @$c [$reason]\n" if $DEBUG;
95}
96
97
98sub drop {
99 my($self, $checker, $reason) = @_;
100 if (ref($checker) ne "CODE") {
101 # make it so
102 if (!defined $checker) {
103 $checker = sub { 1 }; # drop all of them
104 }
105 elsif (_looks_like_number($checker)) {
106 my $age_limit = $checker;
107 my $time_limit = time - $age_limit;
108 $reason ||= "older than $age_limit";
109 $checker = sub { $_[3] < $time_limit };
110 }
111 else {
112 my $type = $checker;
113 $reason ||= "drop $type";
114 $checker = sub { $_[1] eq $type }; # match on type
115 }
116 }
117 $reason ||= "drop";
118
119 local $SIG{__DIE__}; # don't interfere with eval below
120 local $@;
121 my @c;
122 for (@{$self->{cc_conns}}) {
123 my $drop;
124 eval {
125 if (&$checker(@$_)) {
126 $self->dropping($_, $reason);
127 $drop++;
128 }
129 };
130 push(@c, $_) unless $drop;
131 }
132 @{$self->{cc_conns}} = @c;
133}
134
135
136sub prune {
137 my $self = shift;
138 $self->drop(sub { !shift->ping }, "ping");
139}
140
141
142sub get_types {
143 my $self = shift;
144 my %t;
145 $t{$_->[1]}++ for @{$self->{cc_conns}};
146 return keys %t;
147}
148
149
150sub get_connections {
151 my($self, $type) = @_;
152 my @c;
153 for (@{$self->{cc_conns}}) {
154 push(@c, $_->[0]) if !$type || ($type && $type eq $_->[1]);
155 }
156 @c;
157}
158
159
160sub _looks_like_number {
161 $_[0] =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
162}
163
1641;
165
166
167__END__
168
169=head1 NAME
170
171LWP::ConnCache - Connection cache manager
172
173=head1 NOTE
174
175This module is experimental. Details of its interface is likely to
176change in the future.
177
178=head1 SYNOPSIS
179
180 use LWP::ConnCache;
181 my $cache = LWP::ConnCache->new;
182 $cache->deposit($type, $key, $sock);
183 $sock = $cache->withdraw($type, $key);
184
185=head1 DESCRIPTION
186
187The C<LWP::ConnCache> class is the standard connection cache manager
188for LWP::UserAgent.
189
190The following basic methods are provided:
191
192=over
193
194=item $cache = LWP::ConnCache->new( %options )
195
196This method constructs a new C<LWP::ConnCache> object. The only
197option currently accepted is 'total_capacity'. If specified it
198initialize the total_capacity option. It defaults to the value 1.
199
200=item $cache->total_capacity( [$num_connections] )
201
202Get/sets the number of connection that will be cached. Connections
203will start to be dropped when this limit is reached. If set to C<0>,
204then all connections are immediately dropped. If set to C<undef>,
205then there is no limit.
206
207=item $cache->capacity($type, [$num_connections] )
208
209Get/set a limit for the number of connections of the specified type
210that can be cached. The $type will typically be a short string like
211"http" or "ftp".
212
213=item $cache->drop( [$checker, [$reason]] )
214
215Drop connections by some criteria. The $checker argument is a
216subroutine that is called for each connection. If the routine returns
217a TRUE value then the connection is dropped. The routine is called
218with ($conn, $type, $key, $deposit_time) as arguments.
219
220Shortcuts: If the $checker argument is absent (or C<undef>) all cached
221connections are dropped. If the $checker is a number then all
222connections untouched that the given number of seconds or more are
223dropped. If $checker is a string then all connections of the given
224type are dropped.
225
226The $reason argument is passed on to the dropped() method.
227
228=item $cache->prune
229
230Calling this method will drop all connections that are dead. This is
231tested by calling the ping() method on the connections. If the ping()
232method exists and returns a FALSE value, then the connection is
233dropped.
234
235=item $cache->get_types
236
237This returns all the 'type' fields used for the currently cached
238connections.
239
240=item $cache->get_connections( [$type] )
241
242This returns all connection objects of the specified type. If no type
243is specified then all connections are returned. In scalar context the
244number of cached connections of the specified type is returned.
245
246=back
247
248
249The following methods are called by low-level protocol modules to
250try to save away connections and to get them back.
251
252=over
253
254=item $cache->deposit($type, $key, $conn)
255
256This method adds a new connection to the cache. As a result other
257already cached connections might be dropped. Multiple connections with
258the same $type/$key might added.
259
260=item $conn = $cache->withdraw($type, $key)
261
262This method tries to fetch back a connection that was previously
263deposited. If no cached connection with the specified $type/$key is
264found, then C<undef> is returned. There is not guarantee that a
265deposited connection can be withdrawn, as the cache manger is free to
266drop connections at any time.
267
268=back
269
270The following methods are called internally. Subclasses might want to
271override them.
272
273=over
274
275=item $conn->enforce_limits([$type])
276
277This method is called with after a new connection is added (deposited)
278in the cache or capacity limits are adjusted. The default
279implementation drops connections until the specified capacity limits
280are not exceeded.
281
282=item $conn->dropping($conn_record, $reason)
283
284This method is called when a connection is dropped. The record
285belonging to the dropped connection is passed as the first argument
286and a string describing the reason for the drop is passed as the
287second argument. The default implementation makes some noise if the
288$LWP::ConnCache::DEBUG variable is set and nothing more.
289
290=back
291
292=head1 SUBCLASSING
293
294For specialized cache policy it makes sense to subclass
295C<LWP::ConnCache> and perhaps override the deposit(), enforce_limits()
296and dropping() methods.
297
298The object itself is a hash. Keys prefixed with C<cc_> are reserved
299for the base class.
300
301=head1 SEE ALSO
302
303L<LWP::UserAgent>
304
305=head1 COPYRIGHT
306
307Copyright 2001 Gisle Aas.
308
309This library is free software; you can redistribute it and/or
310modify it under the same terms as Perl itself.
Note: See TracBrowser for help on using the repository browser.