4

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
}
Peter Stuifzand
  • 5,084
  • 1
  • 23
  • 28
  • Is this code on the server side, or on the client side? Have you investigated implementing a SIGHUP handler (this would probably only work if you have control of the server side)? – Jonah Bishop Jan 23 '13 at 21:31
  • This code runs server side in Starman. I want to be able to send a HUP signal and make the server reload. This is builtin for Starman. The problem is that the children don't restart, because the socket doesn't close. – Peter Stuifzand Jan 23 '13 at 21:42
  • How do you start the server? Using `plackup` the default is to run your psgi file in the master process before forking and using `starman`the default is to run the psgi file in the child processes. This is difference can be very important when allocation resources inside the psgi file. – pmakholm Jan 24 '13 at 09:20
  • I started with plackup. I changed that to Starman. It seemed I had an -R in the startup file. This made Starman preload the .psgi file. I removed the -R and added error checking to the bind and connect. Also I used STARMAN_DEBUG=1 and ran into a few error messages from the bind. – Peter Stuifzand Jan 24 '13 at 12:06

1 Answers1

2

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.

pmakholm
  • 1,488
  • 8
  • 23