fork. CGI-скрипт ждет выполнения проги.
Хотя, если нет цели сделать всё уж очень красиво - можно обойтись и очень простым способом - из скрипта с надписью "подождите" перекидывать через секунду на yourScript.pl?checkstatus, а в checkstatus ничего не запускать, только проверять, выполнили ли программу; если выполнили - выдавать результта, если нет - говорить "подождите" и через секунду опять перекидывать.
Соответственно, с ajax - то же самое, только ничего никто перезагружать не будет, а браузер каждую секунду будет сам обращаться к checkstatus, не перезагружая при этом страницу; и, если есть результат - выводить его.
перекидывать через секунду на yourScript.pl?checkstatusс помощью
<META HTTP-EQUIV="Refresh" content="1;URL=yourScript.pl?checkstatus">
?
или как-то еще?
Либо так, либо AJAX, суть одна. Разница только в клиенте — в js и html.
или как-то еще?ну еще джаваскрипт таймер можно поставить
Этот код после запуска mainprog3.pl тормозит секунд пять и выдает результат tick=2, а я хотел бы, чтобы он каждую секунду обновлял страницу.
Если же закомментить все кроме редиректа в первом условии и
if($tick == 0){
print $q->redirect('mainprog3.pl?tick=1');
}
и заменить строчки
if(!fileready{
# if($tick<5){
на
# if(!fileready{
if($tick<5){
то скрипт отлично обновляется каждую секунду и через пять секунд выдает результат $tick=5 и все хорошо.
------------------------------------------------------
mainprog3.pl
#!/usr/bin/perl -w
use strict;
use CGI;
my $q = new CGI;
my $tick = $q->param('tick');
if(!defined $tick){$tick = 0}
my $pid;
if($tick == 0){
if(!defined ($pid = fork{
die "can't fork $!";
}
elsif($pid){
#parent
print $q->redirect('mainprog3.pl?tick=1');
}
else{
#child
exec ("/usr/bin/perl", "./otherprog.pl") || die $!;
}
}
else{
$tick++;
print "Content-type: text/html\n\n";
print "<html>\n<head>\n";
if(!fileready{
# if($tick<5){
print "<META HTTP-EQUIV=\"Refresh\" content=\"1;URL=mainprog3.pl?tick=$tick\">\n";
}
else{
print "finihed<br>\n";
print "<a href=\"mainprog3.pl\">again</a><br>\n"
}
print "current tick = $tick\n";
print "</head>\n</html>\n";
}
sub fileready{
my $path = "/home/cosrad/users/m_users/";
my $flag = 0;
if(-e $path."result.txt"){
$flag = 1;
}
return($flag);
}
otherprog.pl
#!/usr/bin/perl -w
$sum = 0;
$path = "/home/cosrad/users/m_users/";
unlink($path."result.txt");
for($i=0; $i<10000000; $i++){
$sum += $i;
}
open OUT, ">".$path."result.txt" || die $!;
flock OUT, 2;
print OUT "other sum=", $sum, "\n";
close OUT;
-------------------------
Ajax тут совершенно не нужен; очнитесь, люди!
Есть в никсах отличный вызов wait. Ман, к примеру, тут:
http://linux.about.com/od/commands/l/blcmdl2_wait.htm
Соотв., в перле или что ты там юзаешь, есть интерфейс к ней, который
тебе и нужно использовать. Не нужны никакие таймеры или файлы - сразу по завершении программы тебе возвращается управление.
Итак:
1) юзер кликает на кнопку, javascript-ом пишешь ему Please Wait.... и
отсылаешь запрос
2) форкаешь скрипт, исполняешь дитём твою прогу, папе говоришь wait и
после неё пишешь обработку результатов работы проги и возврат http response.
Иначе будут проблемы.
Во, я тоже так думаю, она может при некоторых входных данных работать минут по десять.
Во, я тоже так думаю, она может при некоторых входных данных работать минут по десять.Зависит от задачи. Я примерно в таком случае открыл демоном TCP-порт (локально с которым общается скрипт. Но там была работа демона, которую никто вызывает. То есть там это точно необходимо. А здесь - ХЗ.
Кстати, у меня демон тоже на perl, работы у него не много - (Daemon::Generic)
Ещё и какой-то пул задач придётся делать, значит. Иначе тебе пицот штук таких запустят в фоне.
#!/usr/bin/perl -w
use strict;
#use Time::local;
my $pid;
my $path = "/home/cosrad/users/m_users/";
if(!defined ($pid=fork{
print "I can't fork\n";
exit(0);
}
elsif($pid){
print "Content-type: text/html\n\n";
print "I'm parent<br>\n";
print "start time: ", localtime . "<br>\n";
wait;
print "Parent finished waiting<br>\n";
open(IN, $path . "result.txt");
print <IN>, "<br>\n";
print "end time: ", localtime . "<br>\n";
}
else{
exec("/usr/bin/perl","./otherprog.pl");
}
А если бы ты в ИЕ это смотрел - тебе бы через 30 секунд сказали "не удаётся отобразить страницу".
Это жутко неправильный подход, который опирается на то, что клиент будет столько времни ждать, что сервер разрешит столько времени выполнять скрипт, и что соединение вдруг за эти 10 минут не порвётся.
AJAX тут действительно ни при чём, можно просто страницу обновлять, как я сказал выше. AJAX - это только для красоты (не очень приятно, когда каждую секунду страница перерисовывается, дёргается прогрессбар и раздаётся характерный щелчок).
А если бы ты в ИЕ это смотрел - тебе бы через 30 секунд сказали "не удаётся отобразить страницу".юзай https, будет тебе счастье в виде >30сек на ожидание
юзай https, будет тебе счастье в виде >30сек на ожиданиеОт возможности сделать таймаут >30 секунд такой способ становится лучше и правильнее?
Оставить комментарий
Elina74
Есть у меня сервер. На нем лежат: перловый скрипт и скомпилированная прога. Работает апач.Я из скрипта запускаю прогу. Прога что-то долго делает. Я не хочу ждать того момента, пока она закончит работу, поэтому делаю fork и запускаю прогу с помощью exec. Другая часть скрипта, которая продолжает работать после разветвления, пишет на экран сообщение типа "подождите пожалуйста". До этого момента у меня уже все написано и работает.
Хотелось бы чтобы после этого скрипт автоматически перегружался и проверял, выполнилась ли до конца прога или нет. Для этого можно пользоваться тем, что прога в конце своей работы создает маленький текстовый файлик. Если прога не закончила работать, писать на экран какую-нибудь постоянно обновляющуюся информацию, например текущее время или номер попытки.
Я пока не в курсе, как вышеописанное называется, поэтому и спрашиваю о терминологии.
Если вас не затруднит, опишите хотя бы в общих словах, как лучше такой скрипт написать. Или дайте ключевые слова. Или рабочий скрипт.