LWP::UserAgent получить обратный вызов с таймаутом

Потерялся ли блок с этим кодом, если время истекло (2 секунды), или get повторить попытку загрузки пропущенного фрагмента?

use LWP::UserAgent;

my $url = '...';
my $file_name = '...';
my $ua = LWP::UserAgent->new();

open my $fh, '>>:raw', $file_name or die $!;
my $res = $ua->get( 
    $url,
    ':content_cb' => sub {
        my ( $chunk, $res, $proto ) = @_;
        eval {
            local $SIG{ALRM} = sub { die "time out\n" };
            alarm 2;
            print $fh $chunk;
            alarm 0;
        };
        # ...
    },
);
close $fh;

2 ответа

Решение

Если 'content_cb' обратный вызов вызывается для чанка, это означает, что чанк был успешно возвращен из запроса. LWP::UserAgent На этом этапе слой выполнил свою работу (по отношению к этому фрагменту). Ваша программа отвечает за то, что вы делаете с чанком. LWP::UserAgent не имеет представления о том, как ваша программа устанавливает или обрабатывает системные сигналы, поэтому она не может повторить любой запрос или повторно уведомить вашу программу о каком-либо фрагменте в ответ на системный сигнал или любое другое событие, которое происходит в контексте ваша программа (и это вне контекста LPW::UserAgent).

Кроме того, следует отметить, что даже если вы установите LWP::UserAgent свойство тайм-аута, которое применяется к ожидающим действиям сервера (например, вообще отвечает на запрос или отправляет следующий блок), затем LWP::UserAgent даже не отправит запрос в случае такого тайм-аута. Модуль просто не предназначен для этого ни при каких обстоятельствах:

Запросы отменяются, если в течение тайм-аута не наблюдается никаких действий при подключении к серверу.

Вы всегда можете повторно отправить запрос в своем коде, если происходит какой-либо тайм-аут или если ваш код считает, что он не получил достаточных данных ответа от сервера.

Если вас беспокоит время ожидания, используйте метод времени ожидания. В вашем коде, когда приходит кусок данных, LWP::UserAgent вызывает ваш ':content_cb' обратный вызов, и повторная попытка не производится.

ИМО не имеет смысла обрабатывать таймаут таким образом, потому что это никогда не произойдет (если print $fh $chunk; занимает время).

Другие вопросы по тегам