2014-10-27 3 views
1

Я пытаюсь создать асинхронный клиент запрос HTTP, используя следующий исходный код:Почему объект URI не может найти метод «схема»?

#!perl 

use URI; 
use DDP; 
use threads; 
use Thread::Queue; 
use LWP::UserAgent; 

use constant NUM_WORKERS => 25; 

my $req_q = Thread::Queue->new(); 
my $res_q = Thread::Queue->new(); 

my @urls = ("http://google.com", "http://web.de"); 

my @workers; 
for (1 .. NUM_WORKERS) { 
    push @workers, async { 
     my $ua = LWP::UserAgent->new(); 
     while (my $req = $req_q->dequeue()) { 
      $res_q->enqueue($ua->request($req)); 
     } 
    }; 
} 

for my $url (@urls) { 
    $req_q->enqueue(HTTP::Request->new(GET => $url)); 
} 

$req_q->enqueue(undef) for @workers; 

for (1 .. @urls) { 
    my $res = $res_q->dequeue(); 
    p $res; 
} 

$_->join() for @workers; 

К сожалению, я получаю сообщение об ошибке:

400 Can't locate object method "scheme" via package "URI::http"

Это должно быть проблемой URI модуль, но если я использую URI-пакет в других скриптах работает нормально.

Я попытался обновить URI до URI-1.64 (обновлен от 1.60), протестирован на Fedora (x86_64 GNU/Linux) perl 5.16 и на ubuntu (i686 athlon i386 GNU/Linux) perl 5.14.

например
$perl -MURI -E'say $INC{"URI.pm"}; say URI->VERSION; say URI->new("http://www.google.com/")->scheme' 
$/home/xxxxx/perl5/lib/perl5/URI.pm 
$1.64 
$http 

Любая идея, что было бы наилучшим способом для устранения неполадок?

+0

Сообщение об ошибке разочаровывает. Есть ли еще? –

+0

400 выход -> это все – ovntatar

+0

Какая версия LWP? – ysth

ответ

3

Используется original code Thread :: Queue :: Any вместо Thread :: Queue, поскольку он обрабатывает объекты немного лучше. Однако в исходном коде были исправлены две ошибки (теперь они исправлены).

use Thread::Queue::Any 1.03 qw(); 
... 
my $req_q = Thread::Queue->new(); 
my $res_q = Thread::Queue->new(); 

должен быть

use Thread::Queue::Any 1.03; # Must call import. 
... 
my $req_q = Thread::Queue::Any->new(); 
my $res_q = Thread::Queue::Any->new(); 

Thread :: Queue :: Любой делает работу в import, что там не должно быть, так что моя обычная практика не вызывая import обратный эффект.

Эти незначительные изменения позволят коду работать.


При желании продолжать использовать Thread :: Queue, похоже, вы должны загрузить модули совместно используемых объектов перед вызовом use threads; (я думаю, что вы будете экономить память, так что это хорошая идея, чтобы сделать независимо от того, что.) URI динамически загружает URI :: HTTP, так что вам нужно добавить

use URI::http; 

или

BEGIN { URI->new('', 'http') } 

перед тем use threads;

Это поможет вам решить эту проблему (и в другую).

+0

perfect @ikegami отлично работает с Thread :: Queue :: Any 1.14 не с 1.03 -> однако thx – ovntatar

+2

1.03 указывает минимум. Код основан на функции, введенной в 1.03. – ikegami

+0

, используя ваше предложение с помощью Thread :: Queue и BEGIN {URI-> new ('', 'http')}. Контент-ответ: Невозможно найти метод объекта «FETCH» через пакет «threads» :: shared :: tie "на /usr/share/perl5/vendor_perl/HTTP/Headers.pm строке 183. странно .. – ovntatar

Смежные вопросы