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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> создать паузы между запросами в AnyEvent::HTTP 
:(
    Опции темы
slavenk
Дата 1.8.2013, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


TheAthlete
*


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

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



Здравствуйте!
 Есть следующий псевдокод (выкачиваются страницы):

Код

 for my $url (@urls) {
 http_get $url, $headers, sub { ... }
 }


 Мне нужно создать паузы между запросами в размере примерно 0,5с. Подскажите пожайлуста, как реализовать данный функционал?
PM MAIL ICQ Skype   Вверх
ginnie
Дата 1.8.2013, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



slavenk, а как Вы уже пробовали, но не получилось? Мне в голову приходит только очевидный вариант, наверное, я неверно понял задачу.
Паузу менее секунды можно задать, например, используя функцию Time::HiRes::usleep() или select(undef, undef, undef, 0.5);

Это сообщение отредактировал(а) ginnie - 1.8.2013, 15:18


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
slavenk
Дата 1.8.2013, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


TheAthlete
*


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

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



Пытался через AnyEvent->timer, но выдает ошибку типа segmentation failed.
PM MAIL ICQ Skype   Вверх
ginnie
Дата 1.8.2013, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



timer удобно использовать для обработки таймаутов, для Вашей задачи достаточно
Код

for my $url (@urls) {
    http_get $url, $headers, sub { ... };
    select(undef, undef, undef, 0.5);
}



--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
slavenk
Дата 1.8.2013, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


TheAthlete
*


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

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



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

Просто, если урлов будет много, не хочется завалить сервер запросами.

Добавлено через 59 секунд
Скорее всего нужно использовать AnyEvent->timer
PM MAIL ICQ Skype   Вверх
ginnie
Дата 1.8.2013, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



Предлагаю попробовать такой вариант: запросы формируем не до запуска цикла обработки, а внутри него:
создаем таймер, в функции которого добавляем запрос, проверяем есть ли еще url, если есть, создаем новый таймер.


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
slavenk
Дата 1.8.2013, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


TheAthlete
*


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

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



Цитата(ginnie @  1.8.2013,  15:50 Найти цитируемый пост)
Вы, возможно, неверно представляете как работает код?

Скорее всего да. 

Суть работы такая: есть список урлов с одного домена (сайта), нужно выкачать страницы по этим урлам. Нужно сделать так, чтобы не сильно нагружать сервер с этого домена. Как вариант я решил использовать задержку при запросе (аналогично как это делает пользователь).

Как я понял, запросы на сервер отправляются с задержкой в 0.5 сек, а ответы приходят асинхронно? Просто выглядит это так, что сначала каждые 0.5 сек отдаются запросы, а только потом асинхронно возвращаются ответы. 

Так оно и есть: если написать такой код:

Код

for my $url (@urls) {
    http_get $url, $headers, sub { say $url };
    select(undef, undef, undef, 0.5);
    say 'yes';
}


то сначала будут выдаваться "Yes" по количеству урлов, и только потом выдаются ответы.

А можно как-то посмотреть запросы, которые отдает http_get?
PM MAIL ICQ Skype   Вверх
ginnie
Дата 1.8.2013, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



slavenk, скорее всего там все сложнее и запросы тоже делаются асинхронно, т.е. http_get только формирует задание на запрос, а сам запрос отправляется на сервер уже в цикле обработки. Поэтому я предложил выше делать запросы в цикле обработки.


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
Pfailed
Дата 1.8.2013, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



sleep и его аналог select делать в anyevent цикле нельзя, нужно использовать timer.
Вам нужно послать запрос на следующую ссылку через 5 секеунд после того как придёт ответ на предыдущую или через 5 секунд после того как будет послан запрос на предыдущую?


--------------------
PM MAIL   Вверх
DurRandir
Дата 2.8.2013, 00:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Код

for my $url (@urls) {
    http_get $url, $headers, sub { say $url };
    select(undef, undef, undef, 0.5);
    say 'yes';
}


В этом коде пауза 0.5 бессмысленна. Вы не передаёте управление в AnyEvent (и, соответственно, не даёте возможность ему отправить в сеть запросы) внутри цикла. Да и вообще, использование в event-driven приложении sleep/select - нехороший признак)

Правильный вариант будет выглядеть как-то так:

Код

my $cv = AnyEvent->condvar;

sub cb {
  ... #process request

  if (scalar @urls) {
    send_request;
  } else {
    $cv->send;
  }
}

sub send_request {
  AnyEvent->timer after => 0.5, cb => sub {
    http_get pop @urls, $headers, \&cb;
  }
}

send_request; $cv->recv;

PM   Вверх
ginnie
Дата 2.8.2013, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



DurRandir, скажите, а чем Ваш вариант отличается от простой отсылки запросов в цикле вообще без использования AnyEvent?
Мне кажется, что не надо привязывать отсылку нового запроса к обработке результата предыдущего.


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
DurRandir
Дата 3.8.2013, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



slavenk так и не сказал, ему важна пауза между отправкой или между обработкой. Этот вариант легко переделывается на паузу между отправкой.
PS: да, никакой разницы, если опрашиваем один сайт. А если несколько, поддерживая для каждого свою очередь запросов?
PM   Вверх
slavenk
Дата 5.8.2013, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


TheAthlete
*


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

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



Нужна пауза между отправкой, т.е. между запросами
PM MAIL ICQ Skype   Вверх
slavenk
Дата 5.8.2013, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


TheAthlete
*


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

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



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


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

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


 




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


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

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