Log message for revision 126562: Added a separate option, stop-timout, to control how long to wait for a graceful shutdown. Previously, this was controlled by backoff-limit, which didn't make much sense.
Changed: U zdaemon/trunk/CHANGES.txt U zdaemon/trunk/src/zdaemon/README.txt U zdaemon/trunk/src/zdaemon/component.xml U zdaemon/trunk/src/zdaemon/tests/tests.py U zdaemon/trunk/src/zdaemon/zdoptions.py U zdaemon/trunk/src/zdaemon/zdrun.py -=- Modified: zdaemon/trunk/CHANGES.txt =================================================================== --- zdaemon/trunk/CHANGES.txt 2012-06-04 13:06:20 UTC (rev 126561) +++ zdaemon/trunk/CHANGES.txt 2012-06-04 14:17:09 UTC (rev 126562) @@ -2,13 +2,16 @@ Changelog =========== - -2.0.5 (unreleased) +3.0.0 (unreleased) ================== -- Nothing changed yet. +- Added a separate option, stop-timout, to control how long to wait + for a graceful shutdown. + Previously, this was controlled by backoff-limit, which didn't make + much sense. + 2.0.4 (2009-04-20) ================== Modified: zdaemon/trunk/src/zdaemon/README.txt =================================================================== --- zdaemon/trunk/src/zdaemon/README.txt 2012-06-04 13:06:20 UTC (rev 126561) +++ zdaemon/trunk/src/zdaemon/README.txt 2012-06-04 14:17:09 UTC (rev 126562) @@ -398,6 +398,16 @@ status code in this list makes zdaemon give up. To disable this, change the value to an empty list. +stop-timeout + Command-line option: -T or --stop-timeout SECONDS + + This defaults to 500 seconds (5 minutes). + + When a stop command is issued, a SIGTERM signal is sent to the + process. zdaemon waits for stop-timeout seconds for the + process to gracefully exit. If the process doesn't exit in + that time, a SIGKILL signal is sent. + user Command-line option: -u or --user. Modified: zdaemon/trunk/src/zdaemon/component.xml =================================================================== --- zdaemon/trunk/src/zdaemon/component.xml 2012-06-04 13:06:20 UTC (rev 126561) +++ zdaemon/trunk/src/zdaemon/component.xml 2012-06-04 14:17:09 UTC (rev 126562) @@ -185,6 +185,17 @@ </description> </key> + <key name="stop-timeout" datatype="integer" required="no" default="300"> + <description> + When a stop command is issued, a SIGTERM signal is sent to the + process. zdaemon waits for stop-timeout seconds for the + process to gracefully exit. If the process doesn't exit in + that time, a SIGKILL signal is sent. + + This defaults to 500 seconds (5 minutes). + </description> + </key> + <key name="user" datatype="string" required="no"> <description> Modified: zdaemon/trunk/src/zdaemon/tests/tests.py =================================================================== --- zdaemon/trunk/src/zdaemon/tests/tests.py 2012-06-04 13:06:20 UTC (rev 126561) +++ zdaemon/trunk/src/zdaemon/tests/tests.py 2012-06-04 14:17:09 UTC (rev 126562) @@ -38,13 +38,16 @@ zdaemon_loc = os.path.dirname(os.path.dirname(zdaemon.__file__)) zconfig_loc = os.path.dirname(os.path.dirname(ZConfig.__file__)) +def write(name, text): + with open(name, 'w') as f: + f.write(text) def make_sure_non_daemon_mode_doesnt_hang_when_program_exits(): """ The whole awhile bit that waits for a program to start whouldn't be used on non-daemon mode. - >>> open('conf', 'w').write( + >>> write('conf', ... ''' ... <runner> ... program sleep 1 @@ -60,7 +63,7 @@ """ If a program doesn't start, we don't want to wait for ever. - >>> open('conf', 'w').write( + >>> write('conf', ... ''' ... <runner> ... program sleep @@ -82,7 +85,7 @@ configuration arguments. To deal with this, we'll allow duplicate arguments that have the same values. - >>> open('conf', 'w').write( + >>> write('conf', ... ''' ... <runner> ... program sleep 10 @@ -99,6 +102,45 @@ """ +def test_stop_timeout(): + r""" + + >>> write('t.py', + ... ''' + ... import time, signal + ... signal.signal(signal.SIGTERM, lambda *a: None) + ... while 1: time.sleep(9) + ... ''') + + >>> write('conf', + ... ''' + ... <runner> + ... program %s t.py + ... stop-timeout 1 + ... </runner> + ... ''' % sys.executable) + + >>> system("./zdaemon -Cconf start") + . . + daemon process started, pid=21446 + + >>> import threading, time + >>> thread = threading.Thread( + ... target=system, args=("./zdaemon -Cconf stop",), + ... kwargs=dict(quiet=True)) + >>> thread.start() + >>> time.sleep(.2) + + >>> system("./zdaemon -Cconf status") + program running; pid=15372 + + >>> thread.join(2) + + >>> system("./zdaemon -Cconf status") + daemon manager not running + + """ + def setUp(test): test.globs['_td'] = td = [] here = os.getcwd() @@ -123,7 +165,7 @@ for f in test.globs['_td']: f() -def system(command, input=''): +def system(command, input='', quiet=False): p = subprocess.Popen( command, shell=True, stdin=subprocess.PIPE, @@ -132,7 +174,9 @@ if input: p.stdin.write(input) p.stdin.close() - print p.stdout.read(), + data = p.stdout.read() + if not quiet: + print data, p.wait() def checkenv(match): Modified: zdaemon/trunk/src/zdaemon/zdoptions.py =================================================================== --- zdaemon/trunk/src/zdaemon/zdoptions.py 2012-06-04 13:06:20 UTC (rev 126561) +++ zdaemon/trunk/src/zdaemon/zdoptions.py 2012-06-04 14:17:09 UTC (rev 126562) @@ -364,13 +364,16 @@ -h/--help -- print usage message and exit -b/--backoff-limit SECONDS -- set backoff limit to SECONDS (default 10) -d/--daemon -- run as a proper daemon; fork a subprocess, close files etc. - -f/--forever -- run forever (by default, exit when backoff limit is exceeded) + -f/--forever -- run forever (by default, exit when backoff limit + is exceeded) -h/--help -- print this usage message and exit -s/--socket-name SOCKET -- Unix socket name for client (default "zdsock") + -T/--stop-timeout SECONDS -- How long to wait for a graceful exit. -u/--user USER -- run as this user (or numeric uid) -m/--umask UMASK -- use this umask for daemon subprocess (default is 022) -x/--exit-codes LIST -- list of fatal exit codes (default "0,2") - -z/--directory DIRECTORY -- directory to chdir to when using -d (default off) + -z/--directory DIRECTORY -- directory to chdir to when using -d + (default off) action [arguments] -- see below Actions are commands like "start", "stop" and "status". If -i is @@ -386,6 +389,8 @@ ZDOptions.__init__(self) self.add("backofflimit", "runner.backoff_limit", "b:", "backoff-limit=", int, default=10) + self.add("stoptimeut", "runner.stop_timeout", + "T:", "stop-timeout=", int, default=300) self.add("daemon", "runner.daemon", "d", "daemon", flag=1, default=1) self.add("forever", "runner.forever", "f", "forever", flag=1, default=0) Modified: zdaemon/trunk/src/zdaemon/zdrun.py =================================================================== --- zdaemon/trunk/src/zdaemon/zdrun.py 2012-06-04 13:06:20 UTC (rev 126561) +++ zdaemon/trunk/src/zdaemon/zdrun.py 2012-06-04 14:17:09 UTC (rev 126562) @@ -538,7 +538,7 @@ self.proc.kill(signal.SIGTERM) self.sendreply("Sent SIGTERM") self.killing = 1 - self.delay = time.time() + self.options.backofflimit + self.delay = time.time() + self.options.stoptimeut else: self.sendreply("Application already stopped") @@ -551,7 +551,7 @@ self.proc.kill(signal.SIGTERM) self.sendreply("Sent SIGTERM; will restart later") self.killing = 1 - self.delay = time.time() + self.options.backofflimit + self.delay = time.time() + self.options.stoptimeut else: self.proc.spawn() self.sendreply("Application started") _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org https://mail.zope.org/mailman/listinfo/zope-checkins