Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Прерывание $ua->get($url) 
:(
    Опции темы
Gigik
Дата 19.9.2010, 10:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 20.7.2010

Репутация: нет
Всего: нет



Подскажите, как прервать выполнение запроса, когда сервер отвечает, но очень медленно.

В качестве примера привожу код в котором в функции делается несколько запросов гет. Пытаюсь прервать ее выполнение алармами, с таймаутом равным 1 секунде.

Код

#! /usr/bin/perl
use strict;
use LWP;
use Sys::AlarmCall;

    my $url="http://forum.vingrad.ru/index.php?forums=183&cat_forum=forum_id&act=Search&joinname=1&CODE=do_and_show_extern_search&keywords=код";
    my $ua = LWP::UserAgent->new();
    $ua->timeout(1); 
 
    # Вариант Раз
    print "ver. 1\n"; 
    eval {
      local $SIG{ALRM} = sub { die "alarm\n" };
      alarm 1;         # таймаут=1 на alarm
      test();
    };
    if ( $@ eq "alarm\n" ) {
      print "TIMEOUT\n";
    }
    # Вариант Два
    print "ver. 2\n";  
    my $otvet = alarm_call(1, \&test, "");    # таймаут=1 на alarm
  
    # Функция, выполнение которой надо прервать
    sub test(){
     #sleep(2);  # Если открыть эту строку, то alarm нормально отрабатывает
     my $T2 = time();
     for my $i (0..5){
            my $response = $ua->get($url);
     }
     print time() - $T2."\n";
     return "Ok";
    };


У меня результат такой:
ver. 1
3 s
ver. 2
2 s

Т.е видно, что аларм не срабатывает. 
Если в функции с запросами вставить sleep(2), то все отрабатывает как надо.

Как это побороть? Куда смотреть? Что читать?

Это сообщение отредактировал(а) Gigik - 19.9.2010, 10:09
PM MAIL   Вверх
DurRandir
Дата 19.9.2010, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 335
Регистрация: 27.9.2009

Репутация: 1
Всего: 17



У меня есть подозрение, что LWP у себя внутри зовёт alarm (классический способ повесить таймаут на вызов connect() - это как раз обернуть его в alarm()), что сбивает любые внешние настройки. Советую посмотреть на AnyEvent::HTTP, там это можно организовать как-то так:

use EV;
use AnyEvent;
use AnyEvent::HTTP;

my $timer = AnyEvent->timer(
  after => 1,
  cb     => sub {undef $guard},
);
my $guard = http_get ....; #при успехе - надо сбросить $timer

EV::Loop;

Это сообщение отредактировал(а) DurRandir - 19.9.2010, 16:11
PM   Вверх
sir_nuf_nuf
Дата 20.9.2010, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 2
Всего: 31



Цитата(DurRandir @  19.9.2010,  16:09 Найти цитируемый пост)
У меня есть подозрение, что LWP у себя внутри зовёт alarm

Проверьте ваше подозрение и убедитесь что оно не верно.
LWP::UserAgent использует select для чтения из сокета, select позволяет задавать таймауты.
Кстати есть такое ощущение, что таймауты в LWP::UserAgent работают не всегда правильно..


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
DurRandir
Дата 20.9.2010, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 335
Регистрация: 27.9.2009

Репутация: 1
Всего: 17



Таймаут на выборку - да, таймаут на connect() - нет. Если не переводить сокет в неблокирующий режим, то для системного вызова connect() нельзя просто задать таймаут. Но вообще, в LWP::Protocol::http нет чего-то очень уже криминального, при этом задержка в 3 сек у меня воспроизводится. Ручной вызов connect()/select() alarm'ом нормально прерывается.

PS: там таймауты как написано работают - между 2мя чтениями из сокета. Т.е. это не глобальный таймаут.

Это сообщение отредактировал(а) DurRandir - 20.9.2010, 13:12
PM   Вверх
sir_nuf_nuf
Дата 20.9.2010, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 2
Всего: 31



Цитата(DurRandir @  20.9.2010,  13:10 Найти цитируемый пост)
Таймаут на выборку - да, таймаут на connect() - нет

Точно!

Именно поэтому то я и использоватл eval / alarm для обработки timeout. 
А то запамятовал уже чем мне стандартный не подходил..


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl: CGI программирование"
korob2001
sharq
  • В этом разделе обсуждаются вопросы относящиеся только к CGI программированию
  • Если ваш вопрос не относится к системному или CGI программированию, задавайте его в общем разделе
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", качать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: разработка для Web | Следующая тема »


 




[ Время генерации скрипта: 0.0467 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.