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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сравнение многопоточности и Async, Parallel, Кто нибудь реально пробовал??? 
:(
    Опции темы
burakov
Дата 12.5.2011, 11:31 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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




Написал грабер на основе
HTTP-Async-0.09.tar.gz
вот инфу нашел отсюда http://www.snippy.ru/snippet/1708-perl-asi...-http-klientov/

И вообщем сравниваю свой многопоточный на threads Сделанный и новый на async: многопоточный реально работает быстрее -  хотя количество потоков ставлю 20 - как по умолчанию параметр slots у этого async... По идее должно быть одинаково...

Кто нибудь делал граберы на async, LWP::Parallel и т.п. сравнивал их производительность с реальным многопоточным решением??? Почему разница в скорости?







--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
Pfailed
Дата 12.5.2011, 11:49 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Когда речь идёт о вводе/выводе использование потоков просто избыточно, особенно таких тяжёлых, как в perl.
Единственно для чего тут соит применить потоки это разбить процесс на кол-во потоков равных количеству процессоров, а в каждом уже использовать неблокирующий ввод/вывод. Такой вариант будет быстрее создания отдельного потока для каждого соединения. Плюс потребует гораздо меньше памяти.
Составляйте минимальный пример обоих варинатов и показывайте. Там уже можно будет сказать почему первое быстрее второго или наоборот.



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


Опытный
**


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

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



Код

sleep $self->poll_interval;


Ололо! Модуль жжот) 

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


Опытный
**


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

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



Цитата(DurRandir @ 12.5.2011,  13:21)
Код

sleep $self->poll_interval;


Ололо! Модуль жжот)

Учитывая, что по дефолту poll_interval = 0.05, а sleep принимает только целочисленные аргументы, эта конструкция эквивалентна sleep(0), т.е. пустой конструкции.
Другая более очевидная проблема этого модуля - синхронные запросы dns. А один из таких запросов в худшем случае может заблокировать всю программу на минуты. Один из модулей где решена эта проблема носит название AnyEvent::HTTP.



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


Опытный
**


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

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



Ну не знаю, грабер на потоках работает так как ему и положено.

И так быстро как захочешь - поставил 2 потока - медленнее, поставил 20 - быстрее.
Нареканий к нему нет. Хоть и потоки много памяти занимают и т.д. - главное работает как и задумывалось, 

а вот грабер на async ведет себя непонятно - ставишь 
ему slots = 20 - он вообще замирает, ставишь slots = 2 - вроде как работает быстрее, то есть ведет себя прямо противоположно ожидаемому.

алгоритм грабера таков:

1. $async -> add (Стартовый URL)
 
while ( my $res = $async -> wait_for_next_response) {  
    1. Сохраняю контент и ищу новые ссылки - пишу их в БД
    2. Выбираю из БД ссылки и добавляю и делаю $async -> add (url)
}


Все вроде бы понятно - просто работает такая схема непонятно...

poll_interval
 Задержка - 0,05 секунды - маленькая. ее можно в расчет не брать. Грабер виснет - на гораздо более продолжительное время...


Синхронные запросы ДНС- в многопоточном грабере - тоже ведь ДНС синхронно запрашивается ???? однако все работает быстро и ничего не вешается на минуты и более...

Сейчас, конечно посмотрю HTTP::Event, но все же...


--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
Pfailed
Дата 12.5.2011, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Еще немного посмотрел в HTTP::Async. Его вторая беда - блокирующийся connect.
Простой скрипт выводящий из строя всю Async'хронность
Код

use HTTP::Async;
use HTTP::Request;
use strict;

my $async = HTTP::Async->new;
warn 'before first add: ', time();
$async->add(HTTP::Request->new(GET => 'http://perlmonks.org'));
warn 'after first add: ', time();

warn 'before second add: ', time();
$async->add(HTTP::Request->new(GET => 'http://waitpid.org'));
warn 'after second add: ', time();

warn 'before third add: ', time();
$async->add(HTTP::Request->new(GET => 'http://google.ru'));
warn 'after third add: ', time();



Сервер добавляемый вторым в данный момент выключен. В итоге весь скрипт зависает на неопределенное время.
Итого: HTTP::Async для реальных задач использовать я не рекомендую.



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


Опытный
**


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

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



А что порекомендуете использовать для реальных задач?
Чтобы было уже проверено? и можно было отказаться от threads... (иногда таки дает ошибку памяти под WIN32, да и код посложнее)

ParallelUserAgent-2.57.tar.gz?


--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
DurRandir
Дата 12.5.2011, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



>Pfailed
Там есть импорт правильного слипа из Time::HiRes

>burakov
Был же уже назван модуль - AnyEvent::HTTP. Есть альтернативные подходы - к примеру, IO::Lambda.
PM   Вверх
Pfailed
Дата 12.5.2011, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(DurRandir @  12.5.2011,  16:00 Найти цитируемый пост)
Там есть импорт правильного слипа из Time::HiRes

Ага точно, значит еще 1 минус в карму этому модулю  smile 


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


Шустрый
*


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

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



threads можно юзать там, где нет сложных структур данны, т.е. где можно не слишком загонятся с синхронизацией.
В то время как Anyevent::HTTP позволяет вообще не задумываться не о какой синхронизации и работать почти как с однопоточным скриптом.
Вот только если с threads ещё можно написать чтото через жопу и оно будет работать(возможно даже без глюков), то от anyevent быстро остановится, так как для этого достаточно если один коллбэк загнётся.
У меня есть скрипт на Anyevent::HTTP и через него прошло уже как минимум 60к линков и без каких либо проблем.
PM MAIL WWW   Вверх
EcSYZ
Дата 12.5.2011, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



На счёт сравнение скорости:
Так как Anyevent(и все другие событийные машины) не чистая многопоточность, то в случае если один коллбэк задержится, то следующая пачка запросов будет ждать этот 1 коллбэк.
Это конечно не особо приятно, но если вы пишите не паука для гугла который должен обходить милионы сайтов супер-пупер-мего быстро, то с этими небольшими потерями можно смирится.
PM MAIL WWW   Вверх
burakov
Дата 13.5.2011, 09:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Ну не знаю, 
на Anyevent::HTTP у меня ума не хватило, зато я адаптировал 
под себя ParallelUserAgent-2.57.tar.gz

Код

use strict;
use warnings;

$SIG{PIPE} = 'IGNORE';  
use LWP::Parallel::UserAgent;  

my @urls    = (  
  'http://libnote.ru',  
);  
my $ua = LWP::Parallel::UserAgent->new();  
$ua->agent("Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)");  
$ua->nonblock (1);  
$ua->duplicates (1);  
$ua->max_hosts (5); # sets maximum number of locations accessed in parallel
$ua->max_req  (5); # sets maximum number of parallel requests per host

my $max_connects = 3;  
my $cnt = @urls > $max_connects ? $max_connects : @urls;  
add_request() foreach (1 .. $cnt);  

sub add_request {  
    # my $url = shift @urls or return;  
    # my $req = HTTP::Request->new(GET => $url);  
    # $ua->register($req);  
    
    while (scalar (@urls) > 0) {
        my $url = shift (@urls); 
        my $req = HTTP::Request->new (GET => $url);  
        $ua->register($req);
    }
}   

{  
no warnings;  
sub LWP::Parallel::UserAgent::on_return  {  
  my ($self, $request, $response, $entry) = @_;  
  if($response->is_success()) {  
    print "Succeeded for '", $response->request->url, "'\n";  
    
    get_url_from_content ($response -> content);
  }  
  add_request();  
 }  
sub LWP::Parallel::UserAgent::on_failure { add_request() }  
}  
my $entries = $ua->wait ();  



sub get_url_from_content {
    my $content = shift;
    my @pattern1 = ();
    push (@pattern1, 'href="(.+?)"');
    push (@pattern1, 'href=\'(.+?)\'');
    
    my @pattern2 = ();
    push (@pattern2, '/noty.html?'); 
    push (@pattern2, '/noty/.+?.html$'); 
    push (@pattern2, '/uchebniki.html$'); 
    push (@pattern2, '/uchebniki.html?'); 
    push (@pattern2, '/uchebniki/.+?.html$'); 
    
    foreach (@pattern1) {
        while ($content =~ /$_/ig) {
            my $url = $1;
            foreach (@pattern2) {
                if ($url =~ /$_/i) {
                    $url = 'http://libnote.ru'.$url;
                    push (@urls , $url);
                }
            }
        } 
    }
}



Грабит локально с denwera (на этой же машине стоит).
И не выдерживает никакой конкуренции по скорости с грабером на threads, который я думаю написан как раз через жопу на коленке - ибо я наверное по другому и не умею. Вообщем недоволен я остался LWP::Parallel. На Threads Выставил 5 потоков (больше нельзя ибо памяти не хватает smile) и только успевай контент получать - а тут 5 потоков и тормоза - грабит как в 1 поток (может чего в коде не так?).

Может кто поделится кодом с Anyevent::HTTP, чтобы сравнить скорости, уж больно в документации мало примеров ... Спасибо.


--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
EcSYZ
Дата 13.5.2011, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код

#!/usr/bin/perl
$|=1;
use v5.10;
use strict;
use warnings;
use AnyEvent::HTTP;
$AnyEvent::HTTP::MAX_PER_HOST=4;

my $links=[];
for(1 .. 100){
    push @$links, 'http://localhost/test.pl?id='.$_;
}

my $cv = AnyEvent->condvar;
my $count=0;
 
foreach my $link (@$links){
   $count++;
   http_request(
      GET     => $link,
      headers => { "user-agent" => 'Opera/9.80 (X11; Linux x86_64; U; ru) Presto/2.8.131 Version/11.10' },
      timeout => 5,
      sub {
         #say $_[1]->{Status}." : $count : $link";
         (--$count)==0 ? $cv->send : undef;
   });
}
$cv->recv;

Генериться 100 ссылок.
4 потока:
Код

real    0m3.163s
user    0m0.220s
sys    0m0.035s


10 потоков:
Код

real    0m2.714s
user    0m0.222s
sys    0m0.039s

----------------------
На локалхосте больше 10 коллбэков оказывается без мазы, а для нета работал с 20-40.

Это сообщение отредактировал(а) EcSYZ - 13.5.2011, 14:11
PM MAIL WWW   Вверх
EcSYZ
Дата 13.5.2011, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Тоже, но только на threads:
Код

#!/usr/bin/perl
$|=1;
use v5.10;
use strict;
use warnings;
use threads;
use threads::shared;
use Mojo::UserAgent;

my $ua = Mojo::UserAgent->new;
my $links=[];
share($links);
for(1 .. 100){
    push @$links, 'http://localhost/test.pl?id='.$_;
}

for(1 .. 4){
    threads->create(\&run,$_);
}
foreach(threads->list) { $_->join; }

sub run
{
    while(scalar @$links != 0){
        $ua->get(pop @$links);
    }
}


4 потока:
Код

real    0m4.102s
user    0m0.798s
sys    0m0.098s


10 потоков:
Код

real    0m3.881s
user    0m1.157s
sys    0m0.162s


PS: с LWP::UserAgent выходит ещё медленней, примерно на 100-400ms (подсчёт примерный).
PS2: хотел ещё LWP::Parallel::UserAgent затестить, но он у меня даже не собрался ...

Это сообщение отредактировал(а) EcSYZ - 13.5.2011, 16:46
PM MAIL WWW   Вверх
burakov
Дата 16.5.2011, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



попробовал под себя адаптировать код AnyEvent::HTTP, но не получается... где то ошибка.
почему то колбэк (sub) отрабатывает один раз...
подозреваю, что это из за неправильно расставленных
$cv->send; #???
$cv->recv; #???
Но я так из описания модуля и не нашел этих методов на cpan.org что они делают и как их использовать, чтобы все работало...
А может дело и не в этом...

В чем ошибка? Спасибо.


Код

$|=1;
# use v5.10;

use strict;
use warnings;
use clear_str;
use AnyEvent::HTTP;
$AnyEvent::HTTP::MAX_PER_HOST=4;

my @links = (); 
push @links, 'http://libnote.ru';

my $cv = AnyEvent->condvar;
my $count=0;

while (1) {
    my $link = shift (@links); 
    if (defined $link ) {
        get ($link);
    }
}
 
sub get {
    my $link = shift or return;
    print $link ."\n";
    
    #my $link = shift (@links) or return;
    #print $link ."\n";
  
   http_request (
      GET     => $link,
      headers => { "user-agent" => 'Opera/9.80 (X11; Linux x86_64; U; ru) Presto/2.8.131 Version/11.10' },
      timeout => 5,
      
    sub {
            my ($body, $hdr) = @_;
            $count ++;
            print $_[1]->{Status}." : $count : $link". "\n" ;            
            
            my $content = $body;
            $content = utf8_to_win1251 ($content); 
            my $clear_str = clear_str  -> new ($content); 
            $content = $clear_str -> delete_1 ();
            $content = $clear_str -> delete_4 ();
            $clear_str = undef;
            get_url_from_content ($content);  #ищу и фильрую ссылки и добавляю их к глобал @links

            $cv->send; #???
        }
    );    
    $cv->recv; #???
}



sub get_url_from_content  {
    my $content = shift;
    my @pattern1 = ();
    push (@pattern1, 'href="(.+?)"'); 
    push (@pattern1, 'href=\'(.+?)\''); 
    my @urls = ();
    
    foreach (@pattern1) {
        while ($content =~ /$_/g) {
            push (@urls, $1);
        }
    }
    my @pattern2 = ();
    push (@pattern2, '/noty.html$'); 
    push (@pattern2, '/noty.html?'); 
    push (@pattern2, '/noty/.+?.html$'); 
    
    foreach my $url (@urls) {
        foreach my $str2 (@pattern2) {
            if ($url =~ /$str2/i) {
                my $host = 'http://libnote.ru';
                if ($url !~ /^$host/i) {$url = $host.$url; }
                push (@links, $url);
                # print $url."\n";
            }
        }
    }
}

sub utf8_to_win1251 {
    use Encode qw (encode decode); 
    my $str = shift;
    $str = encode ('cp1251', decode ('utf8', $str)); 
    return $str;
}




--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
DurRandir
Дата 16.5.2011, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Каждый вызов http_request ставит в очередь 1 запрос. Надо 10 параллельных запросов - надо выполнить 10 http_request. Но вызов $cv->recv блокирует дальнейшее выполнение, пока не будет вызван $cv->send (из колбека). И поэтому в очередь ставится всего 1 запрос. 
PM   Вверх
EcSYZ
Дата 17.5.2011, 08:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Вот из другого топика http://forum.vingrad.ru/topic-328733.html :
Код

#!/usr/bin/perl
$|=1;
use v5.10;
use strict;
use warnings;
use AnyEvent::HTTP;

my $threads=20;#кол-во одновременных запросов
my $threads_run=0;
$AnyEvent::HTTP::MAX_PER_HOST=$threads;#меняем дефолтное 4 на нужное нам кол-во одновременных запросов, т.е. 20

my @links;

#...
#подгрузка данных
#...

&cycle_run;

sub cycle_run
{
   while(scalar @links != 0){
      my $cv = AnyEvent->condvar;

      for(1 .. $threads){
         #если ссылок больше нет, то не пытаемся больше стартовать запросы
            last if(scalar @links == 0);
            &run($cv, pop @links);
      }
      last if($threads_run == 0);
      $cv->recv;
   }
}

sub run
{
   my $cv   = shift;
   my $link = shift;

   $threads_run++;
   http_request(
      GET     => $link,
      headers => { "user-agent" => 'Opera/9.80 (X11; Linux x86_64; U; ru) Presto/2.8.131 Version/11.10' },
      #proxy => [$host, $port[, $scheme]]
      timeout => 10,
      sub {
         #разные действия
         (--$threads_run) == 0 ? $cv->send : undef;
      }
   );
}

Вот примерно так. &cycle_run занимается стартом запросов и их отловом, а &run чисто за запросы отвечает и действия с ними.
В &cycle_run 2 цикла - while отвечает за перебор всех ссылок, а for - за создание запросов пачками по N штук.

Тут ещё немного инфы есть: http://likhatskiy.livejournal.com/1966.html
----------------------
Тот пример что я привёл ранее на Anyevent::HTTP не совсем правильный - он начинает обрабатывать 4 запроса, а остальные 96 запихивает в очередь, что не есть гуд.
PM MAIL WWW   Вверх
burakov
Дата 20.5.2011, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Попробовал работать в AnyEvent::HTTP - очень понравилось smile - на мой взгляд - действительно - это лучший модуль из всех паралелл, работает даже быстрее моего много поточного грабера - наверное действительно ДНС как-то кеширует (как в документации написано, если конечно я правильно перевел).
Единственный вопрос возник.
При работе с LWP::useragent, когда заголовки прописываешь, подделываешь не только заголовки как 

в посте выше 
{ "user-agent" => 'Opera/9.80 (X11; Linux x86_64; U; ru) Presto/2.8.131 Version/11.10' }
но и пишешь ему что $ua -> agent ('Opera/9.80 (X11; Linux x86_64; U; ru) Presto/2.8.131 Version/11.10')

Наверное это не одно и тоже, поскольку один хитрый сайт без прописания $ua-agent работать со мной отказался... :(

А как этого агента прописать используя модуль AnyEvent::HTTP , непонятно ...
или все таки 
в заголовке
{ "user-agent" => 'Opera/9.80 (X11; Linux x86_64; U; ru) Presto/2.8.131 Version/11.10' }
и 
$ua -> agent ('Opera/9.80 (X11; Linux x86_64; U; ru) Presto/2.8.131 Version/11.10')
это одно и тоже?


--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
EcSYZ
Дата 20.5.2011, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



headers => { "user-agent" => '...' }, - это тот самый юзер-агент из header`а запроса, даже специально щас проверил.
Вроде там можно ещё какие то замуты производить с Anyevent::Header, но тут я х\з если честно.
PM MAIL WWW   Вверх
burakov
Дата 21.5.2011, 22:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Подскажите еще 
время от времени на одном из сайтов 
при грабке http::Anyevent
выдает код ошибки 596 хрен пойму что он означает, но чувствую, что ошибка происходит из за того, что Anyevent::Header не ждет долгого ответа от сайта (сайт нагружен и подтормаживает отвечать) - есть ли какой параметр чтобы ждать ответа подольше? Вроде у меня выставлено timeout => 5, но что это за таймаут? Ошибается только грабер на HTTP::Anyevent, а многопоточный который вытягивает контент при помощи LWP::UserAgent тянет нормально...

Вот что означает код
596 - errors during TLS negotiation, request sending and header processing.
но что это значит???

--
пробовал менять  timeout, точнее вообще не задавать его... написано что по умолчанию он 300 (непонятно в каких единицах - но как оказалось в секундах?)
так с таким дефолтным тайматом парсер вообще вешается на каком то моменте - это я так понимаю ждет какой то поток (меня об этом предупреждали) ну вообщем и все висит.

Если бы не было у меня моего многопоточного грабера я бы конечно подумал, что URL не отвечает - модуль ждет его timeout а затем по идее выдает код ошибки http. Но многопоточный грабер по всем этим ссылкам (граблю же один и тот же сайт) выдает 200 ОК и довольно быстро безо всякой задержки...

В чем же тут дело?

Это сообщение отредактировал(а) burakov - 21.5.2011, 22:35


--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
JackYF
Дата 22.5.2011, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

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



Пожалуйста, одна тема - один вопрос.




--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
EcSYZ
Дата 22.5.2011, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



timeout => 10 - это в секундах. дефолтное значение помоему 5 минут, что просто ТТ. С дефолтным значением парсер уходит в оооооочень долгое ожидание, по сути не совместимое с жизнью. Обычно хватает 5-10 на таймаут.
Код ошибки точно не помню, но некоторые не правильные урлы будут висеть пока не умрут по тайм ауту, например "http://site1.com/xxx/[email protected]" гарантировано звершается только по тайм ауту.
PM MAIL WWW   Вверх
Pfailed
Дата 22.5.2011, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(burakov @  21.5.2011,  22:13 Найти цитируемый пост)
errors during TLS negotiation, request sending and header processing.

Похоже на ошибку установления https соединения.
Если сайт долго не отвечает это не должно тормозить всю программу. Если тормозит значит у вас что-то неверно в самой программе.


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


Шустрый
*


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

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



Цитата(Pfailed @ 22.5.2011,  14:09)
Похоже на ошибку установления https соединения.
Если сайт долго не отвечает это не должно тормозить всю программу. Если тормозит значит у вас что-то неверно в самой программе.

Это не чистая многопоточность, так что притормаживания в любом случае будут заметны на урлах с ошибками(которые умирают по таймауту).
PM MAIL WWW   Вверх
Pfailed
Дата 22.5.2011, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(EcSYZ @  22.5.2011,  17:47 Найти цитируемый пост)
Это не чистая многопоточность, так что притормаживания в любом случае будут заметны на урлах с ошибками(которые умирают по таймауту). 

С чего это вдруг? Тормоза будут заметны когда не будет справляться процессор или когда программа написана с ошибками, что в случае с событийно-ориентированным кодом очень легко.
Умирают по таймауту? Почему? Затянувшийся connect() или sysread()? Все эти операции производятся в неблокирующем режиме, поэтому не могут приостановить программу.


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


Опытный
**


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

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



хрен поймешь
зависимость работы парсера от таймаут такая
если ставлю его = 5. то URL (одни и те же) идут то ответом 200, то 596,
если увеличиваю его по дефолту (то есть по сути сильно увеличиваю), то парсер подвисает.
Я пытаюсь Вас спросить - что это за параметр таймаут?
Я так для себя понял - что это время ожидания ответа от посланного http запроса, если в течении (когда =5) 5 секкунд ответа нет коннект отбрасывается с каким то кодом ошибки (ну пусть к примеру как у меня 596) так ли это?

Просто когда я использую многопоточный грабер на этом же сайта никакой видимой задержки нет (ну и потоки конечно отследить сложно - они ж в перемешку идут, может какой и подвисает на некоторое время).  Хотя нет - грабил данный сайт в один поток - тоже никаких задержек не было... что то все таки в модуле намудрили...

по поводу того, что сам парсер написан неправильно...

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

Это сообщение отредактировал(а) burakov - 22.5.2011, 21:24


--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
Pfailed
Дата 22.5.2011, 21:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



burakov, приводите минимальный пример где проявляется эта ошибка. Тогда возможно и сможем сказать в модуле проблема или в вашем коде.


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


Опытный
**


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

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



вот подпрограмма, которая берет ссылки из массива и тянет контент

Код

sub make_req {
    my @urls = @_;    @links = ();
    my $count = scalar (@urls);
    
    use AnyEvent::HTTP;
    $AnyEvent::HTTP::MAX_PER_HOST = $threads_all; #количество потоков из ини файла = 4

    my $cv = AnyEvent->condvar;

    foreach my $url (@urls) {
        my $host = $host;        #немного корректирую host, который потом вставляю в http_request
        $host =~ s/http:\/\///g; 
        http_request (
            'GET' => $url,
            headers => { 
                'Host' =>  $host,
                'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16',
            },            
            
            timeout => 5,
            
            sub {
                my ($body, $hdr) = @_;
                print $_[1]->{Status}." : $count : $url". "\n" ;            
                
                if ($_[1]->{Status} == 200) {
                    my $sql = 'update '.$table.' set state= "pass" where url="'.$url.'"';
                    $work_mysql -> run_query ($sql);

#работаю с контентом, сохраняю его в файл и т.п.
###############################################
                    my $content = $body;
                    my $clear_str = clear_str  -> new ($content); 
                    $content = $clear_str -> delete_1 ();
                    $content = $clear_str -> delete_4 ();
                    $clear_str = undef;
                    
                    my $workdir = get_base_path ().'/html'; 
                    my $file = get_file ($url);
                    $file = $workdir.'/'.$file; 
                    print $file."\n";
                    put_content_to_file ($content, $file); 

###############################################                    

                                        get_url_from_content ($content);  #беру ссылки и добавляю их к глобал @links
                    
                } else {
                    my $sql = 'update '.$table.' set state="false" where url="'.$url.'"';
                    $work_mysql -> run_query ($sql);
                }
                if (--$count == 0) {$cv->send;} else {undef;}
            }
        );    
    }
    $cv->recv;
    $cv = undef;
}


Данный парсер был опробован на нескольких сайтах (и локально на денвере и в интернете) и только на этом возникают ошибки 596.




--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
Pfailed
Дата 22.5.2011, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Не годится. Давайте код, который можно запустить и увидеть ошибки.


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


Шустрый
*


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

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



Кстате я тоже с таким сталкивался - был сайт, на котором паук сильно тупил. Сначала я пытался выцепить ссылки на которых тупит - оказались ссылки со встроенным видео плеером(хотя это никак не может ведь вызвать тормоза). Потом выцепил некоторые тупящие ссылки и ещё по 20 ссылок до и после для теста: ссылки работали нормально.
Короче, ситуация весьма неясная ... при 20 потоках грабер иногда убивает запросы по тайм-ауту, а при 1 потоке всё идёт ровно.
------------
Если урл убивается по тайм-ауту, то статус 597 (только что проверил)


PM MAIL WWW   Вверх
burakov
Дата 22.5.2011, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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


--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
burakov
Дата 23.5.2011, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



А как с помощью AnyEvent::HTTP
сохранить картинку ?
все таки решил не отказываться от него, ибо если уж тянет контент - то делает это очень быстро.



--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
djusha
Дата 23.5.2011, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Хорошая тема.
Многопоточность это хорошо... но хочется чтобы каждый запрос шел с разных IP адресов...

IP у хостера можно купить... не проблема...

При работе с  LWP::UserAgent можно использовать 
@LWP::Protocol::http::EXTRA_SOCK_OPTS = (LocalAddr => $ips, Reuse => 1 );
и подставлять разные $ips на каждый поток...(ну как то так)


а как обстоит дело при работе с AnyEvent::HTTP ?

не прокси... именно IP...





Это сообщение отредактировал(а) djusha - 23.5.2011, 12:49
PM WWW   Вверх
burakov
Дата 23.5.2011, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



А как с помощью AnyEvent::HTTP
сохранить картинку ?
все таки решил не отказываться от него, ибо если уж тянет контент - то делает это очень быстро.



--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
Pfailed
Дата 23.5.2011, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(djusha @  23.5.2011,  12:48 Найти цитируемый пост)
При работе с  LWP::UserAgent можно использовать 
@LWP::Protocol::http::EXTRA_SOCK_OPTS = (LocalAddr => $ips, Reuse => 1 );

В LWP это делается более прямо если почитать документацию: LWP::UserAgent->new(local_address => $ip)


Цитата(djusha @  23.5.2011,  12:48 Найти цитируемый пост)
а как обстоит дело при работе с AnyEvent::HTTP ?

Нормально. В описании параметра on_prepare сказано об этом.

Добавлено через 5 минут и 16 секунд
Цитата(burakov @  23.5.2011,  12:49 Найти цитируемый пост)
А как с помощью AnyEvent::HTTP
сохранить картинку ?

Также как и всё остальное. Если файл большой и хочется по мере получения писать его в файл на локальном носителе, то см. описание параметра on_body.


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


Новичок



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

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



Цитата(Pfailed @ 23.5.2011,  14:01)
Цитата(djusha @  23.5.2011,  12:48 Найти цитируемый пост)
При работе с  LWP::UserAgent можно использовать 
@LWP::Protocol::http::EXTRA_SOCK_OPTS = (LocalAddr => $ips, Reuse => 1 );

В LWP это делается более прямо если почитать документацию: LWP::UserAgent->new(local_address => $ip)


Цитата(djusha @  23.5.2011,  12:48 Найти цитируемый пост)
а как обстоит дело при работе с AnyEvent::HTTP ?

Нормально. В описании параметра on_prepare сказано об этом.

за LWP::UserAgent->new(local_address => $ip) спасибо... действительно проще и правильней

$ua ->local_address($ips); 

и все дела...

а вот с on_prepare => $callback->($fh) не обессудте... недоходит...

можете примерчиком побаловать?


PM WWW   Вверх
Pfailed
Дата 23.5.2011, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Судя по документации так
Код

http_get 'http://www.google.ru/',
    on_prepare => sub {
        bind($_[0], AnyEvent::Socket::pack_sockaddr(0, v10.192.130.15)); # bind to specified ip address
        15; # connect timeout
    },
    sub {
        print $_[0];
    };


Проверяйте


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


Новичок



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

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



Pfailed,  спасибо за подсказку!

кстати, видел Вашу статью - "use Coro, история успеха" http://forum.vingrad.ru/forum/topic-317827...vent/index.html

интересна связка Coro с LWP::UserAgent

возник вопрос... делали ли Вы какие либо замеры по производительности...

Если бы Вы сейчас начали делать что либо с НУЛЯ, что бы Вы выбрали,  

AnyEvent::HTTP  или Coro  в связке с LWP::UserAgent  ?

Это сообщение отредактировал(а) djusha - 24.5.2011, 09:24
PM WWW   Вверх
Pfailed
Дата 24.5.2011, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



djusha, замеров не делал, но здравый смысл подсказывает, что AnyEvent::HTTP быстрее, а Coro + LWP легче при написании кода.
Если нужно что-то сильно производительное, скажем больше 500 одновременных соединений, я бы озадачился AnyEvent::HTTP иначе удобнее Coro.


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


Новичок



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

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



Цитата(burakov @ 22.5.2011,  21:17)
хрен поймешь
зависимость работы парсера от таймаут такая
если ставлю его = 5. то URL (одни и те же) идут то ответом 200, то 596,
если увеличиваю его по дефолту (то есть по сути сильно увеличиваю), то парсер подвисает.
Я пытаюсь Вас спросить - что это за параметр таймаут?
Я так для себя понял - что это время ожидания ответа от посланного http запроса, если в течении (когда =5) 5 секкунд ответа нет коннект отбрасывается с каким то кодом ошибки (ну пусть к примеру как у меня 596) так ли это?

Просто когда я использую многопоточный грабер на этом же сайта никакой видимой задержки нет (ну и потоки конечно отследить сложно - они ж в перемешку идут, может какой и подвисает на некоторое время).  Хотя нет - грабил данный сайт в один поток - тоже никаких задержек не было... что то все таки в модуле намудрили...

по поводу того, что сам парсер написан неправильно...

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

А скрипт запускаете из винды или и линукса?

просто я озадачился примерно этим же...

если запускаю скрипт на AnyEvent::HTTP из винды,  и делаю запрос на какой либо сайт в инете, то все нормально...

если делаю запрос на сайт, который находится этой же машине, на виртуальной машине VMware, под CentOS55, то получаю ошибку 595....

LWP к этому же сайту при запросах не имеет проблем... есть над чем репу почесать...



PM WWW   Вверх
EcSYZ
Дата 25.5.2011, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Ну, некоторые моменты в данном деле остаются не ясны, но я уже начал приписывать к своему пауку log4perl, а потом ещё и через прокси пущу ... тогда мож что и выяснится.
А пока что остаётся предполагать, что все проблемы вызваны влиянимем марсианских бурь  smile 
PM MAIL WWW   Вверх
burakov
Дата 25.5.2011, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Скрипт я запускаю из под WinXP, который стоит на локальной машине, подключенной к инету.


--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
djusha
Дата 1.6.2011, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Pfailed @ 23.5.2011,  15:26)
Судя по документации так
Код

http_get 'http://www.google.ru/',
    on_prepare => sub {
        bind($_[0], AnyEvent::Socket::pack_sockaddr(0, v10.192.130.15)); # bind to specified ip address
        15; # connect timeout
    },
    sub {
        print $_[0];
    };


Проверяйте

да, в том виде, как есть работает....

Код
 bind($_[0], AnyEvent::Socket::pack_sockaddr(0, v10.192.130.15));



но мне IP адреса по очереди перебирать нужно или рандомно.... не могу понять....

Простой пример... вот так, без кавычек работает...

Код
 
$ips = v10.192.130.15;

bind($_[0], AnyEvent::Socket::pack_sockaddr(0, $ips));


Если IP адрес брать в кавычки, то нет... в цикле тоже не получается...

вот часть кода... код с одним IP естественно работает... нужно чтобы работало со списком IP из файла...


Подскажите, ато уже по разному перепробовал... ума никак не дам...

Это сообщение отредактировал(а) djusha - 5.6.2011, 16:01
PM WWW   Вверх
Pfailed
Дата 1.6.2011, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Если я правильно понял вопрос: v192.168.75.85 это тоже, что  AnyEvent::Socket::parse_ipv4("192.168.75.85")


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


Новичок



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

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



Цитата(Pfailed @ 1.6.2011,  15:49)
Если я правильно понял вопрос: v192.168.75.85 это тоже, что  AnyEvent::Socket::parse_ipv4("192.168.75.85")



Хех... спасибо!!! все, заработало, разобрался smile

Осталось понять, каким образом IP последовательно гонять, вместо генератора рандомных чисел... что то он не совсем рандомно делает...


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

Это сообщение отредактировал(а) djusha - 1.6.2011, 17:54
PM WWW   Вверх
djusha
Дата 1.6.2011, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(burakov @ 25.5.2011,  20:26)
Скрипт я запускаю из под WinXP, который стоит на локальной машине, подключенной к инету.

ну не знаю... я все же озаботился, поставил виртуальную машину VMware... на нее Linyx... CentOS... хотя лучше бы было FreeBSD, но с ней не получилось общюю папку(Shared Folders) с виндовс сделать

сейчас у меня все скрипты физически находятся на диске винды... 

как и положено D:/home/юзер....

эта же папка является общей в VMware и ссылка... тоесть в linux она тоже /home/юзер....


теперь могу одни и те же скрипты одинаково запускать как в linyx так и в винде на денвере...

плюс редактор виндовый... любимый UltraEdit... в общем удобно для отладки...



PM WWW   Вверх
djusha
Дата 3.6.2011, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Снова столкнулся с непонятными для меня вещами...

каким образом можно заставить несколько подпрограмм на AnyEvent работать последовательно, друг за другом?

например, в цикле проверяем сначала $checkOneSite("$domain")... оставляем только нужное... далее проверяем checkSecondSite("$domain")... и так далее...

на LWP это выглядет так:

Код


#!/usr/bin/perl
use strict;
 use warnings;

open (FIN, '<', 'domain.txt') || die 'No read file! \n';

 my $countAll = '0'; my $countGood = '0';
# foreach my $domain ( @domains ) {
while (<FIN>){ # while читает построчно, и не вешает всю память при чтении больших файлов

  $countAll++; # считаем все домены
 my $domain = $_;
 chomp( $domain );

 my ($goodDomainOne, $oneParametr) = checkOneSite("$domain"); #  возвращаем успешно пройденный домен в $goodDomainOne и результат в $oneParametr, возможны еще какие то параметры кроме $oneParametr
# что нибудь делаем, проверяем
        if ($oneParametr) { # только успешно-пройденные

 my ($goodDomainSecond, $secondParametr)  = checkSecondSite("$domain"); # возвращаем успешнопройденный домен в $goodDomainSecond и результат в $secondParametr, возможны еще какие то параметры кроме $secondParametr
 # что нибудь  делаем
         if ($secondParametr) { # только успешнопройденные

  $countGood++; # считаем успешно прошедшие
 print {$fout} "$countAll;$countGood;$goodDomainOne;$oneParametr;$goodDomainSecond;$secondParametr\n";
 print             "$countAll;$countGood;$goodDomainOne;$oneParametr;$goodDomainSecond;$secondParametr\n";

            }
                      }
                                }


close (FIN);




на AnyEvent передать параметры не из подпрограммы вот таким образом ($goodDomainOne, $oneParametr) = checkOneSite("$domain");  не получается 

... return в кулбеке(правильно?) не работает...

Код

                        sub {
                my ($body, $hdr) = @_;
                return $body; # висим...
            }



помогите... как сдесь поступить? туплю...

Это сообщение отредактировал(а) djusha - 4.6.2011, 09:46
PM WWW   Вверх
djusha
Дата 4.6.2011, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



еще...  вот интересная статья.... "Perl: Wrapper для работы с HTTP-запросами" http://www.s3blog.org/ua.html

тоже на AnyEvent::HTTP

могли бы Вы показать рабочий пример... как это использовать?

спасибо заранее!
PM WWW   Вверх
EcSYZ
Дата 4.6.2011, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Статья выше абсолютна бесполезная, так как не нашёл там ничего нового.
Передавать параметры из калбэка return`ом конечно же нельзя, но от этого жизнь сложнее не становится

Это сообщение отредактировал(а) EcSYZ - 4.6.2011, 14:02
PM MAIL WWW   Вверх
djusha
Дата 4.6.2011, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(EcSYZ @ 4.6.2011,  13:43)
Статья выше абсолютна бесполезная, так как не нашёл там ничего нового.
Передавать параметры из калбэка return`ом конечно же нельзя, но от этого жизнь сложнее не становится

ну... Вы для себя ищите, я для себя smile

и все же... пожалуйста... каким образом передавать параметры из калбэка то??
PM WWW   Вверх
EcSYZ
Дата 4.6.2011, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Ну например если используется в объекте, то получив данные, можно засунуть их в тот же объект.
Или например использовать глобальные переменные для их хранения.

Вот ещё могу предложить что посмотреть, мож найдёте что интересное:
http://www.perl-dev.ws/2011/04/anyeventhttp.html
http://www.perl-dev.ws/2011/05/anyeventhttp-2.html
PM MAIL WWW   Вверх
djusha
Дата 4.6.2011, 23:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(EcSYZ @ 4.6.2011,  14:15)
Ну например если используется в объекте, то получив данные, можно засунуть их в тот же объект.
Или например использовать глобальные переменные для их хранения.

Вот ещё могу предложить что посмотреть, мож найдёте что интересное:
http://www.perl-dev.ws/2011/04/anyeventhttp.html
http://www.perl-dev.ws/2011/05/anyeventhttp-2.html

ссылки не открываются... http://www.perl-dev.ws не работает.

но содержимое прочитал... кое что интересное для себя нашел... большое спасибо!

но конкретно, по моей проблеме с калбэком так ума у меня и не добавилось...

единственное, что дошло сделать push

Код

         sub {
                my ($body, $hdr) = @_;
              push @out, "$body : $url \n";
}


далее return @out; в конце подпрограммы...

тогда получается передавать в массив...
@aaa = checkOneSite($domain);
print @aaa;

но в этом случае, все работает как то не так...

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

если с push, то после пуска происходит задержка... они как бы накапливаются... а потом резко выплевываются в терминал...

короче... запутался совсем... пошел спать  smile  smile 
PM WWW   Вверх
shamber
Дата 5.6.2011, 01:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1422
Регистрация: 5.9.2006
Где: Россия

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



Цитата(djusha @  4.6.2011,  23:43 Найти цитируемый пост)
 они как бы накапливаются... 

буфферизация?
PM MAIL Jabber   Вверх
EcSYZ
Дата 5.6.2011, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



х\з, у меня всё из любых стран этого мира открывается  smile 
Может в скрипте стоит сделать:
Код

#!/usr/bin/perl
$|=1;
use common::sense;
...


На счёт данных от запроса, то у меня это в принципе не вызывало никаких проблем.
Например, кусок из моего crawler`а:
Код

sub _run
{
    my $self = shift;
    my $cv   = shift;
    
    my $link = $self->link_get();
    return 0 unless(defined $link);
    
    $self->{workers_run}++;
    http_request(
        GET     => $link,
        headers => { "user-agent" => 'Opera/9.80 (X11; Linux x86_64; U; ru) Presto/2.8.131 Version/11.10' },
        timeout => 5,
        sub {
            if($_[1]->{Status} == 200 && defined $_[0] && $_[1]->{'content-type'}=~/^text\/html/i && $_[0]=~/\<\s*html/i){
                $self->link_push_used('links', $link);
                
                $self->link_push( $self->_parse($link, $_[0], $_[1]) );
            } else {
                $self->link_push_used('failed', $link);
            }
            
            $self->print_stat();
            
            (--$self->{workers_run}) == 0 ? $cv->send : undef;
        }
    );
}

PM MAIL WWW   Вверх
djusha
Дата 8.6.2011, 09:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(EcSYZ @ 5.6.2011,  13:48)
х\з, у меня всё из любых стран этого мира открывается  smile 
Может в скрипте стоит сделать:
Код

#!/usr/bin/perl
$|=1;
use common::sense;
...


На счёт данных от запроса, то у меня это в принципе не вызывало никаких проблем.
Например, кусок из моего crawler`а:
*************************************************

расскажите великий смысл про use common::sense... кроме дополнительной, хоть и незначилетьной нагрузки на сервер...

use strict /warnings не warnings я и так добавлю, много букав не пугает smile можно даже в одну строчку

say state switch - тоже хз... в чем прелесть? понты все сиё... тем более что на серваках perl5.8.8 стоит...

конкретно по Вашему ответу.. Вы вокруг да около... но с моими знаниями... сделал пока push @out, qq($count;$_[1]->{Status}.... а там видно будет...


зы... нужно переделать cpan'овский  модуль с LWP на anyevent.


готов растатся с некоторой наличностью smile

если есть желающие - за подробностями в личку...

PM WWW   Вверх
EcSYZ
Дата 8.6.2011, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код

use common::sense;

Да чисто для понтов юзаю, шоб выпендриться  smile

Цитата

зы... нужно переделать cpan'овский  модуль с LWP на anyevent.

Вот нафига переделывать LWP на anyevent ? Я например не вижу никаких вообще плюсов LWP перед anyevent-http.
Лино у меня уже давно зреет мысль переписать anyevent-http самому и сделать чуть более удобных.
PM MAIL WWW   Вверх
djusha
Дата 8.6.2011, 10:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(EcSYZ @ 8.6.2011,  09:47)
Код

use common::sense;

Да чисто для понтов юзаю, шоб выпендриться  smile

ну а аргументы где в пользу common::sense... оно ж полезнее с аргументами smile

Добавлено @ 10:11
Цитата(EcSYZ @ 8.6.2011,  09:47)

Цитата

зы... нужно переделать cpan'овский  модуль с LWP на anyevent.

Вот нафига переделывать LWP на anyevent ? Я например не вижу никаких вообще плюсов LWP перед anyevent-http.
Лино у меня уже давно зреет мысль переписать anyevent-http самому и сделать чуть более удобных.

перефразирую...

нужно переделать модуль со CPAN, который написан с использованием LWP... чтобы он был на anyevent...

по поводу переписать... чего воду лить то попусту... я выбираю из готового...



Это сообщение отредактировал(а) djusha - 8.6.2011, 10:13
PM WWW   Вверх
Pfailed
Дата 8.6.2011, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



djusha, что за модуль?


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


Новичок



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

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



Цитата(Pfailed @ 8.6.2011,  10:30)
djusha, что за модуль?

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


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

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


 




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


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

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