From 5f52059c9113cda87905fa8484eca2b80c37d210 Mon Sep 17 00:00:00 2001 From: Florent Clairambault Date: Sat, 1 Nov 2014 23:16:57 +0100 Subject: [PATCH] Added a "restartpause" option. * Applied on startup failure aditionnaly to the backoff delay * Applied on bad exit status Default value is 0, which doesn't change the existing behavior. The goal is to impose a minimum delay between restarts to avoid overloading host with restarts. --- supervisor/options.py | 4 +++- supervisor/process.py | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/supervisor/options.py b/supervisor/options.py index e70bbb97e..06f478e48 100644 --- a/supervisor/options.py +++ b/supervisor/options.py @@ -848,6 +848,7 @@ def get(section, opt, *args, **kwargs): autorestart = auto_restart(get(section, 'autorestart', 'unexpected')) startsecs = integer(get(section, 'startsecs', 1)) startretries = integer(get(section, 'startretries', 3)) + restartpause = integer(get(section, 'restartpause', 0)) stopsignal = signal_number(get(section, 'stopsignal', 'TERM')) stopwaitsecs = integer(get(section, 'stopwaitsecs', 10)) stopasgroup = boolean(get(section, 'stopasgroup', 'false')) @@ -948,6 +949,7 @@ def get(section, opt, *args, **kwargs): autorestart=autorestart, startsecs=startsecs, startretries=startretries, + restartpause=restartpause, uid=uid, stdout_logfile=logfiles['stdout_logfile'], stdout_capture_maxbytes = stdout_cmaxbytes, @@ -1711,7 +1713,7 @@ def __repr__(self): class ProcessConfig(Config): req_param_names = [ 'name', 'uid', 'command', 'directory', 'umask', 'priority', - 'autostart', 'autorestart', 'startsecs', 'startretries', + 'autostart', 'autorestart', 'startsecs', 'startretries', 'restartpause', 'stdout_logfile', 'stdout_capture_maxbytes', 'stdout_events_enabled', 'stdout_syslog', 'stdout_logfile_backups', 'stdout_logfile_maxbytes', diff --git a/supervisor/process.py b/supervisor/process.py index b01717585..d329f6fc0 100644 --- a/supervisor/process.py +++ b/supervisor/process.py @@ -171,7 +171,7 @@ def change_state(self, new_state, expected=True): if new_state == ProcessStates.BACKOFF: now = time.time() self.backoff += 1 - self.delay = now + self.backoff + self.delay = now + self.backoff + self.config.restartpause self.state = new_state @@ -531,6 +531,9 @@ def finish(self, pid, sts): # unexpected exit code self.spawnerr = 'Bad exit code %s' % es msg = "exited: %s (%s)" % (processname, msg + "; not expected") + self.delay = now + self.config.restartpause + if self.config.restartpause > 0: + msg += ". Will restart in %s seconds (restartpause)" % self.config.restartpause self.change_state(ProcessStates.EXITED, expected=False) self.config.options.logger.info(msg) @@ -580,7 +583,7 @@ def transition(self): if self.config.options.mood > SupervisorStates.RESTARTING: # dont start any processes if supervisor is shutting down if state == ProcessStates.EXITED: - if self.config.autorestart: + if self.config.autorestart and now > self.delay: if self.config.autorestart is RestartUnconditionally: # EXITED -> STARTING self.spawn()