Safely updating master state in SocketServer with ForkingMixIn

Reid Priedhorsky reid at reidster.net
Mon May 19 20:55:19 EDT 2008


Dear all,

I have a TCP server written using SocketServer with ForkingMixIn.
Servicing connections is CPU-bound and can take several seconds.

I now need a way to safely tell the master process to update its state (by
groveling in a PostgreSQL database, potentially for several seconds). How
can I do this safely?

I thought of two ways:

1. Install a signal handler for SIGHUP and update state when that signal
is received.

2. Stop using ForkingMixIn and fork myself, except when "special" requests
come in requesting a state update, which don't fork.

3. Look for the existence of a file after each request, and if it's there
update state.

Option 2 seemed like it would require duplicating a lot of code from
ForkingMixIn, and Option 3 seems kind of lame, so I started down Option 1.
I produced the following code snippets:

   # main loop
   while True:
      server.handle_request()
      global update_required
      if (update_required):
         # update state
         update_required = False

   # signal handler
   def sighup(signum, frame):
      global update_required
      update_required = True

With this code, if the server is idle, SIGHUP causes it to immediately
drop out of handle_request() and execute the state updating block.

Do I have a race condition here? If the master process receives a SIGHUP
after a new connection starts but before a slave process is forked to
handle it, will that connection be messed up (to use highly technical
language)? Otherwise this technique seems compact and elegant.

Are there other options?

Your help would be much appreciated.

Thanks,

Reid



More information about the Python-list mailing list