Как запустить фоновый процесс с модом perl

Я использую Perl для возврата наборов данных в XML. Теперь я столкнулся с ситуацией, когда мне нужно выполнить некоторую очистку после отправки набора данных клиенту. Но где-то в цепочке mod perl и Apache выходные данные сохраняются до тех пор, пока не вернется мой метод.

Я попытался очистить буферы с помощью таких команд, как.

$| =1;
STDOUT->flush(); # flush the buffer so the content is sent to the client and the finish hook can carry on, with out delaying the return.
if ($mod_perl_io){
    $mod_perl_io->rflush;
}

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

rint $cgi->header(-type => "text/plain; charset=UTF-8", -cookie => $config->{'cookie'});

Все еще не повезло, на самом деле я всегда отправлял правильные заголовки.

Поэтому я считаю, что лучший вариант - просто запустить новый поток и позволить моему методу вернуться. Но когда я создаю новую тему.

use threads ('yield',
             'stack_size' => 64*4096,
             'exit' => 'threads_only',
             'stringify');
my $thr = threads->create('doRebuild', $dbconnect, $dbusername, $dbpassword,  $bindir);
sub doRebuild {
my ($dbconnect, $dbusername, $dbpassword,  $bindir ) = @_;
1;
}

я получаю segfault

[Пятница, 22 февраля 10:16:47 2013] [уведомление] дочерний pid 26076 выходной сигнал Ошибка сегментации (11)

Из того, что я прочитал, это делается модом perl для обеспечения потокобезопасной работы. Не уверен, что это правильно.

Поэтому я подумал, что попробую использовать {exe}

{exec   'perl', "$bindir/rebuild_needed_values.pl", qw('$dbconnect' '$dbusername' '$dbpassword');}

Из того, что я понимаю, это берет на себя процесс из mod perl и не позволяет ему ничего возвращать.

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


person Dan Walmsley    schedule 21.02.2013    source источник
comment
Вы пробовали fork?   -  person mob    schedule 22.02.2013


Ответы (1)


Вы можете использовать fork(), однако я бы рекомендовал http://gearman.org/ для фоновой обработки.

Такое решение, как Gearman, намного лучше, потому что ваш фоновый процесс не входит в цепочку процессов Apache.

Ваш процесс переживет перезапуск Apache, если он реализован с помощью gearman. Это также более безопасно, так как среду Gearman можно запустить в chroot-тюрьме.

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

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

person Tim De Lange    schedule 22.02.2013