Как установить тайм-аут для продолжительной работы Sybase sp в Perl - PullRequest
1 голос
/ 28 сентября 2019

Я вызываю хранимую процедуру, которая удаляет данные из Sybase DB в Perl.Но SP занимает несколько часов, чтобы завершить.Я просто хочу, чтобы sp работал в течение 1 часа, тогда независимо от того, завершается он или нет, я хочу, чтобы коды потом работали.Как я могу это реализовать?

sub DelRef {
    print "starting defRefData\n";
    $db = new Sybapi($user, $password, $server, $margin_database); 
    #the following sql will take hours
    $db->exec_sql("exec CPN_Margins..clean_up_refData_db '$XrefCode'");
}

&DelRef();
print "process is done\n";
$db->close();

Ответы [ 2 ]

4 голосов
/ 28 сентября 2019

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

Альтернативой являетсядля запуска вашего долго выполняющегося кода в фоновом процессе и отслеживания его хода в основном процессе.

# DelRef() might take a while ...
my $start_time = time;
my $pid = fork();
if ($pid == 0) {
    # child process
    DelRef();
    exit 0;
}
# parent process
while (1) {
    use POSIX ':sys_wait_h';   # for &WNOHANG
    my $waitpid = waitpid $pid, &WNOHANG;
    if ($pid == $waitpid) {
        print STDERR "DelRef() finished successfully\n";
        last;
    }
    if (time - $start_time > 3600) {
        print STDERR "DelRef() didn't finish in an hour\n";
        kill 'TERM',$pid;    # optional
        last;
    }
    print STDERR "DelRef() is still running ...\n";
    sleep 60;
}
print STDERR "... the rest of the script ...\n";
1 голос
/ 28 сентября 2019

Вы можете использовать 'alarm' для этого https://perldoc.perl.org/functions/alarm.html

    my $timeout = 3600; # 1hr = 3600 sec
    eval {
        local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
        alarm $timeout;
        $db = new Sybapi($user, $password, $server, $margin_database); 
        $db->exec_sql("exec CPN_Margins..clean_up_refData_db '$XrefCode'");
        alarm 0;
    };
    if ($@) {
        die unless $@ eq "alarm\n";   # propagate unexpected errors
        # timed out
    }
    else {
        # didn't timed out
    }

И что такое Sybapi?В прошлом я использовал 'DBD :: Sybase' для подключения к Sybase ASE (или 'sybperl' в старом унаследованном коде) и 'DBD :: SQLAnywhere' для подключения к Sybase IQ .

...