File Coverage

blib/lib/LWP/UserAgent/Throttled.pm
Criterion Covered Total %
statement 43 43 100.0
branch 13 16 81.2
condition 3 3 100.0
subroutine 8 8 100.0
pod 3 3 100.0
total 70 73 95.8


line stmt bran cond sub pod time code
1             package LWP::UserAgent::Throttled;
2              
3 4     4   647000 use warnings;
  4         25  
  4         139  
4 4     4   21 use strict;
  4         8  
  4         76  
5 4     4   2093 use LWP;
  4         139867  
  4         151  
6 4     4   38 use Time::HiRes;
  4         9  
  4         35  
7 4     4   421 use LWP::UserAgent;
  4         9  
  4         1366  
8              
9             our @ISA = ('LWP::UserAgent');
10              
11             =head1 NAME
12              
13             LWP::UserAgent::Throttled - Throttle requests to a site
14              
15             =head1 VERSION
16              
17             Version 0.08
18              
19             =cut
20              
21             our $VERSION = '0.08';
22              
23             =head1 SYNOPSIS
24              
25             Some sites with REST APIs, such as openstreetmap.org, will blacklist you if you do too many requests.
26             LWP::UserAgent::Throttled is a sub-class of LWP::UserAgent.
27              
28             use LWP::UserAgent::Throttled;
29             my $ua = LWP::UserAgent::Throttled->new();
30             $ua->throttle({ 'www.example.com' => 5 });
31             print $ua->get('http://www.example.com/page1.html');
32             sleep (2);
33             print $ua->get('http://www.example.com/page2.html'); # Will wait at least 3 seconds before the GET is sent
34              
35             =cut
36              
37             =head1 SUBROUTINES/METHODS
38              
39             =head2 send_request
40              
41             See L.
42              
43             =cut
44              
45             sub send_request {
46 9     9 1 8087126 my $self = shift;
47             # my ($request, $arg, $size) = @_;
48 9         22 my $request = $_[0];
49 9         37 my $host = $request->uri()->host();
50              
51 9 100 100     673 if((defined($self->{'throttle'})) && $self->{'throttle'}{$host}) {
52 3 100       15 if($self->{'lastcallended'}{$host}) {
53 2         16 my $waittime = $self->{'throttle'}{$host} - (Time::HiRes::time() - $self->{'lastcallended'}{$host});
54              
55 2 50       12 if($waittime > 0) {
56 2         11479182 Time::HiRes::usleep($waittime * 1e6);
57             }
58             }
59             }
60 9         66 my $rc;
61 9 100       61 if(defined($self->{'_ua'})) {
62 1         19 $rc = $self->{'_ua'}->send_request(@_);
63             } else {
64 8         86 $rc = $self->SUPER::send_request(@_);
65             }
66 9         1217729 $self->{'lastcallended'}{$host} = Time::HiRes::time();
67 9         53 return $rc;
68             }
69              
70             =head2 throttle
71              
72             Get/set the number of seconds between each request for sites.
73              
74             my $ua = LWP::UserAgent::Throttled->new();
75             $ua->throttle({ 'search.cpan.org' => 0.1, 'www.example.com' => 1 });
76             print $ua->throttle('search.cpan.org'), "\n"; # prints 0.1
77             print $ua->throttle('perl.org'), "\n"; # prints 0
78              
79             When setting a throttle it returns itself,
80             so you can daisy chain messages.
81              
82             =cut
83              
84             sub throttle {
85 4     4 1 18436 my $self = shift;
86              
87 4 50       12 return if(!defined($_[0]));
88              
89 4 100       15 if(ref($_[0]) eq 'HASH') {
90 1         2 my %throttles = %{$_[0]};
  1         6  
91              
92 1         5 foreach my $host(keys %throttles) {
93 1         3 $self->{'throttle'}{$host} = $throttles{$host};
94             }
95 1         17 return $self;
96             }
97              
98 3         8 my $host = shift;
99 3 100       24 return $self->{'throttle'}{$host} ? $self->{'throttle'}{$host} : 0;
100             }
101              
102             =head2 ua
103              
104             Get/set the user agent if you wish to use that rather than itself
105              
106             use LWP::UserAgent::Cached;
107              
108             $ua->ua(LWP::UserAgent::Cached->new(cache_dir => '/home/home/.cache/lwp-cache'));
109             my $resp = $ua->get('https://www.nigelhorne.com'); # Throttles, then checks cache, then gets
110              
111             =cut
112              
113             sub ua {
114 1     1 1 4675 my($self, $ua) = @_;
115              
116 1 50       4 if($ua) {
117 1         5 $self->{_ua} = $ua;
118             }
119              
120 1         3 return $self->{_ua};
121             }
122              
123             =head1 AUTHOR
124              
125             Nigel Horne, C<< >>
126              
127             =head1 BUGS
128              
129             Please report any bugs or feature requests to C,
130             or through the web interface at
131             L.
132             I will be notified, and then you'll
133             automatically be notified of progress on your bug as I make changes.
134              
135             =head1 SEE ALSO
136              
137             L
138              
139             =head1 SUPPORT
140              
141             You can find documentation for this module with the perldoc command.
142              
143             perldoc LWP::UserAgent::Throttled
144              
145             You can also look for information at:
146              
147             =over 4
148              
149             =item * MetaCPAN
150              
151             L
152              
153             =item * RT: CPAN's request tracker
154              
155             L
156              
157             =item * CPANTS
158              
159             L
160              
161             =item * CPAN Testers' Matrix
162              
163             L
164              
165             =item * CPAN Ratings
166              
167             L
168              
169             =item * CPAN Testers Dependencies
170              
171             L
172              
173             =back
174              
175             =head1 LICENSE AND COPYRIGHT
176              
177             Copyright 2017-2021 Nigel Horne.
178              
179             This program is released under the following licence: GPL2
180              
181             =cut
182              
183             1; # End of LWP::Throttle