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

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

Perl modules from CPAN that are used in supporting activate.pl, but not part of the Perl core. Only PMs included.

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