ZMQ sockets block when Starman receives HUP

346 views Asked by At

I have the following code. I want to call the $pub->close method when the starman server receives the HUP signal.

  • How do I know that the child process ends?
  • Could I use an END {} block? I tried this and it seems to work when plackup restarts (after an edit). I tried this with starman. I sent the HUP signal, but the children aren't restarted.
  • Should I install a signal handlers for HUP? How does that work?

I want to clean up before the child restarts, if I don't the child process will block.

This is the .psgi file that I use.

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
}
1

There are 1 answers

0
pmakholm On

There is no standard way for PSGI-applications to register a per-process cleanup handler and Starman doesn't seem to implement any thing directly usable. But you could monkey patch Starman to run some code when the process is exiting.

As Starman is based on Net::Server::PreFork and does not use the child_finish_hook() itself, you could just override this Net::Server::PreFork hook by inserting this in your .psgi file:

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

Using a END block for cleaning up (or just depending on the global destructor) might be prevented somehow by ZMQ's internal use of threads and I think it is wisest to leave signal handling to the Net::Server framework.