ParallelUserAgent
view release on metacpan or search on metacpan
lib/LWP/Parallel/UserAgent.pm view on Meta::CPAN
size => $size,
content_size => 0,
redirect_ok => $self->{'handle_response'},
} );
# if the user specified
$entry->redirect_ok($redirect) if defined $redirect;
# store new entry by request (only new entries)
$self->{'entries_by_requests'}->{$request} = $entry;
# new requests are put at the end
# (first make sure we have an array to push things onto)
$self->{'pending_connections'}->{$netloc} = []
unless $self->{'pending_connections'}->{$netloc};
push (@{$self->{'pending_connections'}->{$netloc}}, $entry);
push (@{$self->{'ordpend_connections'}}, $entry);
}
# duplicates handling: remember this entry
if ($handle_duplicates) {
$previous_requests->{$request->url->as_string} = $entry;
}
return;
}
# Create a netloc from the url or return an alias netloc for file: proto
# Fix netloc for file: reqs to generic localhost.file - this can be changed
# if necessary. Test to ensure url->scheme doesn't return undef (JB)
sub _netloc {
my $self = shift;
my $url = shift;
my $netloc;
if ($url->scheme eq 'file') {
$netloc = 'localhost.file';
} else {
$netloc = $url->host_port; # eg www.cs.washington.edu:8001
}
$netloc;
}
# this method will take the pending entries one at a time and
# decide wether we have enough bandwith (as specified by the
# values in 'max_req' and 'max_hosts') to connect this request.
# If not, the entry will stay on the stack (w/o changing the
# order)
sub _make_connections {
my $self = shift;
if ($self->{'handle_in_order'}) {
$self->_make_connections_in_order;
} else {
$self->_make_connections_unordered;
}
}
sub _make_connections_in_order {
my $self = shift;
LWP::Debug::trace('()');
my ($entry, @queue, %busy);
# get first entry from pending connections
while ( $entry = shift @{ $self->{'ordpend_connections'} } ) {
my $netloc = $self->_netloc($entry->request->url);
push (@queue, $entry), next if $busy{$netloc};
unless ($self->_check_bandwith($entry)) {
push (@queue, $entry);
$busy{$netloc}++;
};
};
# the un-connected entries form the new stack
$self->{'ordpend_connections'} = \@queue;
}
# unordered connections have the advantage that we do not have to
# care about screwing up our list of pending connections. This will
# speed up our iteration through the list
sub _make_connections_unordered {
my $self = shift;
LWP::Debug::trace('()');
my ($entry, $queue, $netloc);
# check every host in sequence (use 'each' for better performance)
my %delete;
SERVER:
while (($netloc, $queue) = each %{$self->{'pending_connections'}}) {
# get first entry from pending connections at this host
ENTRY:
while ( $entry = shift @$queue ) {
unless ( $self->_check_bandwith($entry) ) {
# we don't have enough bandwith -- put entry back on queue
LWP::Debug::debug("Not enough bandwidth for request to $netloc");
unshift @$queue, $entry;
# we can stop here for this server
next SERVER;
}
} # of while ENTRY
# mark for deletion if we emptied the queue at this location
LWP::Debug::debug("Queue for $netloc contains ". scalar @$queue . " pending connections");
$delete{$netloc}++ unless scalar @$queue;
} # of while SERVER
# delete all netlocs that we completely handled
foreach (keys %delete) {
LWP::Debug::debug("Deleting queue for $_");
delete $self->{'pending_connections'}->{$_}
}
}
# this method checks the available bandwith and either connects
# the request and returns 1, or, in case we didn't have enough
# bandwith, returns undef
sub _check_bandwith {
my ( $self, $entry ) = @_;
LWP::Debug::trace("($entry [".$entry->request->url."] )");
my($failed_connections, $remember_failures ) =
@{$self}{qw(failed_connections remember_failures)};
my ($request, $response) = ($entry->request, $entry->response);
my $url = $request->url;
my $netloc = $self->_netloc($url);
if ( $remember_failures and $failed_connections->{$netloc} ) {
$response->code (&HTTP::Status::RC_INTERNAL_SERVER_ERROR);
$response->message ("Server unavailable");
# simulate immediate response from server
$self->on_failure ($request, $response, $entry);
( run in 0.689 second using v1.01-cache-2.11-cpan-e93a5daba3e )