LINUX.ORG.RU

perl, timeout при опросе ns серверов


0

1

Доброго времени суток.. при заказе услуги нужно опросить ns-сервера на наличие заданного доменного имени в них.. прерывать текущий опрос при таймауте в 5 секунд.. делаю через Net::DNS::Resolver @ns - список из трех серверов, добавил туда несуществующий четвертый, дабы создать таймаут для проверки our $TIMEOUT = 10;

foreach (@ns)

{

eval

{

local $SIG{ALRM} = sub { die «timeout\n»; };

alarm $TIMEOUT;

$res = Net::DNS::Resolver->new(nameservers => [$_]);

$query = $res->query($domain);

if ($query)

{

print «<?xml version=\„1.0\“ encoding=\„UTF-8\“?><doc><error code=\„8\“>Автоматически сгенерированное доменное имя $domain уже используется другой услугой/товаром. Укажите, пожалуйста, другое.</error></doc>»;

exit;

} alarm 0;

};

alarm 0;

}

alarm 0;

проверяю, заказывая услугу, никакой задержки, хотя таймаут ставил и 50 и 500.. что не так?



Последнее исправление: Yakoot (всего исправлений: 3)

А какая должна быть задержка ? alarm выставляет через сколько должен быть позван соответствующий сигнал. Задержка выставляется через sleep.

Христиматий пример использования alarm

eval {
    local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
    alarm $timeout;
    $nread = sysread SOCKET, $buffer, $size;
    alarm 0;
};
if ($@) {
    die unless $@ eq "alarm\n"; # propagate unexpected errors
    # timed out
} else {
    # didn't
}

vtVitus ★★★★★
()
Ответ на: комментарий от vtVitus

я не о том.. у меня есть три сервера в массиве @ns = {'ns1. . ', 'ns2. . ', 'ns3. . '}; эти сервера реально существуют и в данный момент исправно работают.. но бывают случаи, когда один из них кочевряжится.. тогда при заказе услуги через панель все зависает, из за того что слишком долго не отвечает нужный сервер.. ну так вот, нужно сделать, чтобы если через 5 секунд сервер не ответил - перейти к следующему.. вроде насколько я понял этот код делает то что надо, но нужно это как-то проверить, для этого я добавил в массив четвертый заведомо отсутствующий сервер ns48 к примеру.. поидее он не должен давать ответа, ввиду своего отсутствия, в результате чего я смогу проверить работу 5секундного таймаута.. но вот чот не видно, чтобы панелька затупляла на 5 секунд..

Yakoot
() автор топика
Ответ на: комментарий от Yakoot

О том что сервер не существует ты получаешь ответ мгновенно. почему сервер должен ждать, чтоб сказать, что сервер не зарегистрирован ?
Вставь тупое sleep и проверишь.

vtVitus ★★★★★
()
Ответ на: комментарий от vtVitus

ладно, стираю левый сервер.. получается, если существующий сервер затупит, данный код все таки сработает и перестанет к нему ломиться через $timeout секунд?

Yakoot
() автор топика
Ответ на: комментарий от Yakoot

Твой пример, не знаю. Он без [code] поэтому его тяжело читать.

Смотри мой. Если строка $nread = sysread SOCKET, $buffer, $size; не выполнится за $timeout секунд, то вызовется сигнал ALRM и ответственно процедура die('alarm'); eval перехватит этот die и дальше разгребаешь что случилось - общая ошибка или timeout.

vtVitus ★★★★★
()
Ответ на: комментарий от Yakoot

alarm это операция препятствующая бесконечному ожиданию ответа от dns (в твоем случае), а не валидность или не валидность чего-то бы ни было.

vtVitus ★★★★★
()
Ответ на: комментарий от Yakoot
#!/usr/bin/perl -w
use strict;

my $timeout=3;
local $SIG{ALRM} = sub { die "alarm\n" };

for (my $i=0; $i < 5; $i++) {
        eval {
                print "test $i sec\n";
                alarm $timeout;
                sleep $i;
                alarm 0;
        };
        if ($@) {
                print "timeout $@ \n";
        }
}
user@xxx-svn:~$ ./tt.pl
test 0 sec
test 1 sec
test 2 sec
test 3 sec
timeout alarm

test 4 sec
timeout alarm

user@xxx-svn:~$
vtVitus ★★★★★
()
Ответ на: комментарий от Yakoot

Дни лизбеза на лоре ?

#!/usr/bin/perl -w
use strict;

my $timeout=3;
local $SIG{ALRM} = sub { die "alarm\n"; };

for (my $i=0; $i <= 5; $i++) {
        eval {
                print "test $i sec\n";
                alarm $timeout;
                sleep $i;
                die 'error';
                alarm 0;
        };
        if ($@) {
                if ( $@ eq "alarm\n") {
                        print "timeout\n";
                } else {
                        print "error\n";
                }
        }
}
test 0 sec
error
test 1 sec
error
test 2 sec
error
test 3 sec
timeout
test 4 sec
timeout
test 5 sec
timeout

vtVitus ★★★★★
()
Ответ на: комментарий от vtVitus

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

Yakoot
() автор топика
Ответ на: комментарий от Yakoot

При die 'text' происходит исключение с текстом text
eval это обработчик исключений, он ловит исключение и помещает текст исключения в переменную $@. соответственно, если переменная $@ определена, то было сгенерированно исключение ( это проверяется, как if ($@) {} ). Проверяя text ты можешь детализировать исключение.

vtVitus ★★★★★
()
Ответ на: комментарий от vtVitus

вроде понял.. у меня цикл foreach, в блоке eval сделал sleep 10; после блока добавил next if ($@); поидее тк опрашивает тир сервера, он должен трижды прерваться после 5 секунд, тоесть итого должно пройти 15 секунд, но проходит 30, тоесть 3 слипа..

Yakoot
() автор топика
Ответ на: комментарий от Yakoot

все работает, спасибо большое за помощь)

Yakoot
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.