Как правильно использовать fork () в FastCGI? - PullRequest
3 голосов
/ 07 апреля 2010

У меня есть приложение, работающее под Catalyst + FastCGI. И я хочу, чтобы fork () выполнял некоторую работу в фоновом режиме.
Я давно использовал этот код для простого CGI (и он работал):

defined(my $pid = fork) or die "Can't fork: $!";
if ($pid) {
    # produce some response         
    exit 0;
}

die "Can't start a new session: $!" if setsid == -1;
close STDIN  or die $!;
close STDOUT or die $!;
close STDERR or die $!;
# do some work in background

Я попробовал некоторые варианты этого в FastCGI, но безуспешно. Как делать разветвление в FastCGI?

Обновление: вот что у меня сейчас:

defined(my $pid = fork) or die "Can't fork: $!";
    if ($pid) {
        $c->stash->{message} = 'ok';
        $c->detach($c->view('JSON'));
    }
    die "Can't start a new session: $!" if setsid == -1;
    close STDIN  or die $!;
    close STDOUT or die $!;
    close STDERR or die $!;
    # do some work, then exit() 

Я отправляю запрос с вызовом AJAX, и в консоли firebug появляется ошибка «502 Bad Gateway».

Ответы [ 2 ]

3 голосов
/ 28 июля 2012

Я думаю, что этот FAQ имеет правильный ответ: http://www.fastcgi.com/docs/faq.html#Perlfork

Вы должны сделать $request->Detach(); до разветвления и $request->Attach(); после того, как фрагмент кода разветвления сделан, где $ requestтекущий объект FCGI.По крайней мере, у меня это сработало.

В случае Catalyst :: Engine :: FastCGI вам может потребоваться установить патч Catalyst :: Engine :: FastCGI, чтобы получить доступ к переменной $request, посколькулокальный для метода run () (в версии, которая в данный момент используется на CPAN).

2 голосов
/ 07 апреля 2010

Эта часть не будет хорошо работать с FastCGI:

if ($pid) {
    # print response         
    exit 0;
}

Вы должны выйти из родительского процесса, поэтому он перестанет отвечать на запросы FastCGI.

setsid () и close () должны демонизировать ваш фоновый процесс. Это может или не может быть необходимым в вашем случае.

...