[Zodb-checkins] CVS: ZODB3/zdaemon - zdaemon.py:1.9
Guido van Rossum
guido@python.org
Mon, 11 Nov 2002 17:31:25 -0500
Update of /cvs-repository/ZODB3/zdaemon
In directory cvs.zope.org:/tmp/cvs-serv32635
Modified Files:
zdaemon.py
Log Message:
Add start, stop, restart, and exit commands.
Use backofflimit as select timeout.
Close sockets before exec'ing the application.
=== ZODB3/zdaemon/zdaemon.py 1.8 => 1.9 ===
--- ZODB3/zdaemon/zdaemon.py:1.8 Mon Nov 11 16:41:07 2002
+++ ZODB3/zdaemon/zdaemon.py Mon Nov 11 17:31:25 2002
@@ -24,6 +24,10 @@
status -- report application status (this is the default command)
kill [signal] -- send a signal to the application
(default signal is SIGTERM)
+ start -- start the application if not already running
+ stop -- stop the application if running; daemon manager keeps running
+ restart -- stop followed by start
+ exit -- stop the application and exit
This daemon manager has two purposes: it restarts the application when
it dies, and (when requested to do so with the -d option) it runs the
@@ -285,19 +289,20 @@
sys.stderr = sys.__stderr__ = open("/dev/null", "w")
os.setsid()
+ mood = 1 # 1: up, 0: down, -1: suicidal
appid = 0 # Application pid; indicates status (0 == not running)
def runforever(self):
self.info("daemon manager started")
- while 1:
- if not self.appid:
+ while self.mood >= 0 or self.appid:
+ if self.mood > 0 and not self.appid:
self.forkandexec()
if self.waitstatus:
self.reportstatus()
r, w, x = [self.mastersocket], [], []
if self.commandsocket:
r.append(self.commandsocket)
- timeout = 30
+ timeout = self.backofflimit
try:
r, w, x = select.select(r, w, x, timeout)
except select.error, err:
@@ -320,6 +325,8 @@
self.problem("socket.error in doaccept(): %s" % str(msg),
error=sys.exc_info())
self.commandsocket = None
+ self.info("Exiting")
+ self.exit(0)
def doaccept(self):
if self.commandsocket:
@@ -360,6 +367,41 @@
else:
self.sendreply("Unknown command %r; 'help' for a list" % args[0])
+ def cmd_start(self, args):
+ self.mood = 1 # Up
+ if not self.appid:
+ self.forkandexec()
+ self.sendreply("Application started")
+ else:
+ self.sendreply("Application already started")
+
+ def cmd_stop(self, args):
+ self.mood = 0 # Down
+ if self.appid:
+ os.kill(self.appid, signal.SIGTERM)
+ self.sendreply("Sent SIGTERM")
+ else:
+ self.sendreply("Application already stopped")
+
+ def cmd_restart(self, args):
+ self.mood = 1 # Up
+ if self.appid:
+ os.kill(self.appid, signal.SIGTERM)
+ self.sendreply("Sent SIGTERM; will restart later")
+ else:
+ self.forkandexec()
+ self.sendreply("Application started")
+
+ def cmd_exit(self, args):
+ self.mood = -1 # Suicidal
+ if self.appid:
+ os.kill(self.appid, signal.SIGTERM)
+ self.sendreply("Sent SIGTERM; will exit later")
+ else:
+ self.sendreply("Exiting now")
+ self.info("Exiting")
+ self.exit(0)
+
def cmd_kill(self, args):
if args[1:]:
try:
@@ -397,6 +439,11 @@
" status -- report application status (default command)\n"
" kill [signal] -- send a signal to the application\n"
" (default signal is SIGTERM)\n"
+ "start -- start the application if not already running\n"
+ "stop -- stop the application if running\n"
+ " (the daemon manager keeps running)\n"
+ "restart -- stop followed by start\n"
+ "exit -- stop the application and exit\n"
)
def sendreply(self, msg):
@@ -449,6 +496,10 @@
def startprogram(self):
try:
+ if self.commandsocket:
+ self.commandsocket.close()
+ if self.mastersocket:
+ self.mastersocket.close()
self.blather("about to exec %s" % self.filename)
try:
os.execv(self.filename, self.args)