我有以下代码。我想在starman服务器收到HUP信号时调用$pub->close方法。

  • 我怎么知道子进程结束了?
  • 我可以使用 END {} 块吗?我试过这个,它似乎在 plackup 重新启动时工作(编辑后)。我和starman一起试过这个。我发送了 HUP 信号,但 children 没有重新启动。
  • 我应该为 HUP 安装信号处理程序吗?这是如何运作的?

  • 我想在 child 重新启动之前进行清理,如果我不这样做,子进程将被阻塞。

    这是我使用的 .psgi 文件。
    use ZMQ;
    use ZMQ::Constants ':all';
    use Plack::Builder;
    
    our $ctx = ZMQ::Context->new(1);
    my $pub = $ctx->socket(ZMQ_PUB);
    $pub->bind('tcp://127.0.0.1:5998');
    
    # I want to close the socket and terminate the context
    # when the server is restarted with kill -HUP pid
    # It seems the children won't restart because the sockets isn't closed.
    # The next two lines should be called before the child process ends.
    
    # $pub->close;
    # $ctx->term;
    
    builder {
        $app
    }
    

    最佳答案

    PSGI 应用程序没有标准的方法来注册每个进程的清理处理程序,而且 Starman 似乎没有实现任何直接可用的东西。但是你可以在进程退出时给 Starman 打补丁来运行一些代码。

    由于 Starman 基于 Net::Server::PreFork 并且不使用 child_finish_hook() 本身,因此您可以通过将其插入 .psgi 文件来覆盖此 Net::Server::PreFork 钩子(Hook):

    sub Starman::Server::child_finish_hook {
        $pub->close();
        $ctx->term();
    }
    

    ZMQ 内部使用线程可能会以某种方式阻止使用 END 块进行清理(或仅取决于全局析构函数),我认为将信号处理留给 Net::Server 框架是最明智的。

    关于perl - 当 Starman 收到 HUP 时,ZMQ 套接字会阻塞,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14489522/

    10-12 19:47