gpt4 book ai didi

perl - 我如何使用 Perl FCGI 被杀死?

转载 作者:行者123 更新时间:2023-12-04 08:53:43 40 4
gpt4 key购买 nike

我对 nginx 和 Perl FCGI 模块有一点问题。我的 FCGI 程序中有一个很长的操作,它可能比我用来通信 FCGI 的 Unix 套接字另一端的服务器(或服务器上的用户)生命周期更长。如果 FCGI 请求关闭,我需要在我的程序中使用 FCGI accept() 循环来中断。我尝试安装 INT、TERM 等信号处理程序,但它们什么也没做,因为 nginx 和我的程序之间的唯一通信是通过 FCGI 套接字 AFAIK 进行的。

我也试过this但是我看不到使用 Perl 中的 FCGI 模块通过 FCGI 套接字向 Nginx 发送原始数据或从 Nginx 发送原始数据。有没有一种方法可以在不修改 FCGI 模块以具有“ping”功能的情况下做到这一点?

基本问题是我的程序不知道 nginx 是否终止了 FCGI 请求。

例子:

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

my $fcgi_socket = FCGI::OpenSocket( '/tmp/test.socket', 100000 );
my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV, $fcgi_socket);
REQUEST: while($request->Accept() >= 0) {
#begin handling request
my $result = '';
while (1) { #or select(), etc
if (somehow check whether the fcgi $request is still live) {
next REQUEST;
}
#check for results, set $result if done
}
print $result;
}

最佳答案

您必须使用 FCGI实现 款待 FCGI_ABORT_REQUEST .

不能使用以下内容,因为它们忽略了 FCGI_ABORT_REQUEST :

  • FCGI <=v0.69 (您当前正在使用的那个?)
  • FCGI-Async <=v0.19
  • Net-FastCGI <=v0.08
  • FCGI-EV <=1.0.7

  • 可以使用 以下,其中 对待 FCGI_ABORT_REQUEST :
  • Vitaly Kramskikh's AnyEvent-FCGI

  • 使用 AnyEvent-FCGI 时,检查中止的请求就像调用 $request->is_active() 一样简单,但请记住 is_active()直到 on_request 才会反射(reflect)请求的真实状态处理程序返回,这意味着您必须从 on_request 返回尽快并以某种方式“并行”完成实际工作(您可能不想使用 Perl threads ,但更类似于 continuations )以便给出 AnyEvent当您完成冗长的操作时,循环处理任何进一步的请求(包括 FCGI_ABORT_REQUEST s)的机会。

    我对 AnyEvent不够熟悉确定是否有更好的方法可以做到这一点,但下面是我的看法,首先:
    use AnyEvent;
    use AnyEvent::FCGI;

    my @jobs;
    my $process_jobs_watcher;

    sub process_jobs {
    # cancel aborted jobs
    @jobs = grep {
    if ($_->[0]->is_active) {
    true
    } else {
    # perform any job cleanup
    false
    }
    } @jobs;
    # any jobs left?
    if (scalar(@jobs)) {
    my $job = $jobs[0];
    my ( $job_request, $job_state ) = @$job;
    # process another chunk of $job
    # if job is done, remove (shift) from @jobs
    } else {
    # all jobs done; go to sleep until next job request
    undef $process_jobs_watcher;
    }
    }

    my $fcgi = new AnyEvent::FCGI(
    port => 9000,
    on_request => sub {
    my $request = shift;
    if (scalar(@jobs) < 5) { # set your own limit
    # accept request and send back headers, HTTP status etc.
    $request.print_stdout("Content-Type: text/plain\nStatus: 200 OK\n\n");
    # This will hold your job state; can also use Continutiy
    # http://continuity.tlt42.org/
    my $job_state = ...;
    # Enqueue job for parallel processing:
    push @jobs, [ $request, $job_state ];
    if (!$process_jobs_watcher) {
    # If and only if AnyEvent->idle() does not work,
    # use AnyEvent->timer() and renew from process_jobs
    $process_jobs_watcher = AnyEvent->idle(cb => \&process_jobs);
    }
    } else {
    # refuse request
    $request.print_stdout("Content-Type: text/plain\nStatus: 503 Service Unavailable\n\nBusy!");
    }
    }
    );

    AnyEvent->loop;

    关于perl - 我如何使用 Perl FCGI 被杀死?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2345117/

    40 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com