[Moscow.pm] AnyEven::HTTP перед и после fork с сокетами между процессами
ksvs
ksvs1996 на ymail.com
Вт Окт 15 17:23:23 PDT 2013
Вот упрростил до совсем маленького примерчика.
Запускать так:
- с первым: 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 <mi на ya.ru> wrote:
а ссылку на пример поиграться?
09.10.2013, 07:26, "ksvs" <ksvs1996 на ymail.com>:
> Есть приложение, в котором главный процесс и дочерние общаются между собой по сокетам, используя 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
> moscow-pm на pm.org | http://moscow.pm.org
--
С уважением
Николай Мишин
--
Moscow.pm mailing list
moscow-pm на pm.org | http://moscow.pm.org
Подробная информация о списке рассылки Moscow-pm