Тут виноват не AnyEvent::HTTP, а AnyEvent::DNS, который используетcя AnyEvent::HTTP.

Если чуть изменить ваш примерчик и выкинуть в нем резоливинг www.bing.com, например так:

1) добавить сабу.
my $tcp_connect = sub {
    use AnyEvent::Socket ();
    $_[0] = "204.79.197.200"; # ( www.bing.com => 204.79.197.200 )
    &AnyEvent::Socket::tcp_connect( @_ );
};
2) и заменить в нем
=============================
        http_get $URL, persistent => 0,  sub {
            print "+ $_[1]{Status} $_[1]{Reason} $_[1]{URL}; $$\n";
            syswrite $parent, "pong\n";
        };
=============================
на
        http_get $URL, persistent => 0, tcp_connect => $tcp_connect, sub {
            print "+ $_[1]{Status} $_[1]{Reason} $_[1]{URL}; $$\n";
            syswrite $parent, "pong\n";
        };
=============================


то пример начинает работать.
Возможно AnyEvent::DNS хранит сокеты внутри себя...


16.10.2013 4:23, ksvs пишет:
Вот упрростил до совсем маленького примерчика.
Запускать так:
- с первым: time perl ae_http_slow_simple.pl 1
- без:      time perl ae_http_slow_simple.pl 0

Иногда может повести и "с" отработает быстро.
У меня "без" отрабатывает до 2 секунд. "С" - обычно 15-30 (хотя может и 2).

Знакомый запускал у себя на линоде, так там было пару раз до 5 минут.

Вот этот пример.


$| = 1;
use strict;
use warnings;

use EV;
$EV::FLAG_FORKCHECK = 1;
use AnyEvent;
use AnyEvent::HTTP;

my $URL = "http://www.bing.com";;

if ($ARGV[0]) {
     my $w = AnyEvent->condvar;
     http_get $URL, persistent => 0, keepalive => 0, sub {
         print ". $_[1]{Status} $_[1]{Reason} $_[1]{URL}; $$\n";
         $w->send;
     };
     $w->recv;
     print "...\n";
}

use IO::Socket;
socketpair(my $child, my $parent, AF_UNIX, SOCK_STREAM, PF_UNSPEC) or die 
"socketpair: $!";

my $kid_pid = fork;
defined $kid_pid or die "Can't fork: $!";

unless ($kid_pid) {
     close $child;
     my $w = AnyEvent->condvar;
     my $wr = AnyEvent->io(fh => $parent, poll => "r", cb => sub {
         my $len = sysread $parent, my $buf, 1024;
         unless ($len) {
             # print"child EXIT\n";
             exit;
         };
         print $buf;

         http_get $URL, persistent => 0, sub {
             print "+ $_[1]{Status} $_[1]{Reason} $_[1]{URL}; $$\n";
             syswrite $parent, "pong\n";
         };
     });
     $w->recv;
     exit;
} else {
     close $parent;
     my $i = 0;
     my $w = AnyEvent->condvar;
     my $wr = AnyEvent->io(fh => $child, poll => "r", cb => sub {
         sysread $child, my $buf, 1024;
         # print $buf;
         if (++$i > 3) {
             # print "parent EXIT\n";
             exit;
         } else {
             syswrite $child, "ping $i\n";
         }
     });
     syswrite $child, "ping $i\n";
     $w->recv;
}





On Wednesday, 9 October 2013, 10:03, Nikolay Mishin <[email protected]> wrote:
а ссылку на пример поиграться?


09.10.2013, 07:26, "ksvs" <[email protected]>:
Есть приложение, в котором главный процесс и дочерние общаются между собой по 
сокетам, используя EV модуль.
Дочерние процессы получают информацию от главного, делают HTTP запросы, 
анализируют и возвращают результат главному. В дочерних процессах запросы идут 
параллельно с использованием либо Net::Curl::Multi, либо AnyEven::HTTP.

Все было отлично, пока не понадобилось в главном процессе перед fork, сделать 
HTTMP запрос. LWP использовать можно, но не хочется.
Используемые варианты:
1. Делаем первый запрос при помощи AnyEven::HTTP, дочерние работают с Curl - 
все отлично. Это для проверки.
2. Делаем первый запрос при помощи AnyEven::HTTP на несуществующий адрес, 
дочерние работают с AnyEven::HTTP - все нормально.
3. Делаем первый запрос при помощи AnyEven::HTTP на существующий адрес, работа 
AnyEven::HTTP в дочерних процессах зависает. При этом общение между процессами 
идет: гонял ping для подтверждения того, что EV не завис и система коммуникаций 
между процессами жива.

Может кто-то сталкивался с таким поведением AnyEven::HTTP?

Сделал максимально простой вариант для теста.
В нем с первоначальным вызовом AnyEven::HTTP, в дочернем процессе 
AnyEven::HTTP, стал работать, но очень-очень медленно. Точнее все зависит от 
того, как карты лягут: без первого вызова время выполнения 1,24 секунды, а с 
первым - может быть 21 секунд, а может быть 5 секунд.

Но ведь с Curl работает отлично. Значит дело не в EV, а в AnyEven::HTTP.
Для подтверждения этого вместо первого вызова AnyEven::HTTP, сделал просто 
открытие сокета, EV::WRITE, EV::READ - все работает отлично.

AnyEven::HTTP настраивал, чтобы он закрывал все сокеты. Это перед форком. Да и 
делается ведь EV::break перед форком.

Интересно понять причину этого.

,
--
Moscow.pm mailing list
[email protected] | http://moscow.pm.org


--
С уважением Анатолий.
--
Moscow.pm mailing list
[email protected] | http://moscow.pm.org

Ответить