[Zope-Checkins] CVS: Zope/ZServer/medusa - asyncore.py:1.18 http_server.py:1.32 logger.py:1.16
Chris McDonough
chrism@zope.com
Tue, 11 Jun 2002 18:02:48 -0400
Update of /cvs-repository/Zope/ZServer/medusa
In directory cvs.zope.org:/tmp/cvs-serv24893/medusa
Modified Files:
asyncore.py http_server.py logger.py
Log Message:
These patches provide clean signal handling and logfile rotation to Zope.
All Zope process will respond to signals in the specified manner:
SIGHUP - close open database connections and sockets, then restart the
process
SIGTERM - close open database connections and sockets, then shut down.
SIGINT - same as SIGTERM
SIGUSR2 - rotate all Zope log files (z2.log, event log, detailed log)
The common idiom for doing automated logfile rotation will become:
kill -USR2 `cat /path/to/var/z2.pid`
The common idiom for doing "prophylactic" restarts will become:
kill -HUP `cat /path/to/var/z2.pid`
When a process is interrupted via ctrl-C or via a TERM signal (INT, TERM),
all open database connections and sockets will be closed before
the process dies. This will speed up restart time for sites that
use a FileStorage as its index will be written to the filesystem before
shutdown.
Unspecified signals kill the process without doing cleanup.
=== Zope/ZServer/medusa/asyncore.py 1.17 => 1.18 ===
self.handle_close()
return ''
+ if why[0] == EAGAIN:
+ # Happens as a result of a nonfatal signal when select is
+ # interrupted
+ return ''
else:
raise socket.error, why
@@ -524,12 +528,15 @@
# NOTE: this is a difference from the Python 2.2 library
# version of asyncore.py. This prevents a hanging condition
# on Linux 2.2 based systems.
- while 1:
+ i = 0
+ while i < 5: # this is a guess
try:
return apply (os.read, (self.fd,)+args)
except exceptions.OSError, why:
if why[0] != EAGAIN:
raise
+ else:
+ i = i + 1
def send (self, *args):
return apply (os.write, (self.fd,)+args)
=== Zope/ZServer/medusa/http_server.py 1.31 => 1.32 ===
self.total_clients.increment()
try:
- conn, addr = self.accept()
+ tup = self.accept()
except socket.error:
# linux: on rare occasions we get a bogus socket back from
# accept. socketmodule.c:makesockaddr complains that the
# address family is unknown. We don't want the whole server
# to shut down because of this.
- self.log_info ('warning: server accept() threw an exception', 'warning')
+ self.log_info ('warning: server accept() threw an exception',
+ 'warning')
+ self.total_clients.decrement()
return
+ try:
+ conn, addr = tup
except TypeError:
- # unpack non-sequence. this can happen when a read event
- # fires on a listening socket, but when we call accept()
- # we get EWOULDBLOCK, so dispatcher.accept() returns None.
- # Seen on FreeBSD3.
- self.log_info ('warning: server accept() threw EWOULDBLOCK', 'warning')
+ # unpack non-sequence. this can happen when a read event
+ # fires on a listening socket, but when we call accept()
+ # we get EWOULDBLOCK, so dispatcher.accept() returns None.
+ # Seen on FreeBSD3 and Linux.
+ #self.log_info ('warning: server accept() returned %s '
+ # '(EWOULDBLOCK?)' % tup, 'warning')
+ self.total_clients.decrement()
return
-
+
self.channel_class (self, conn, addr)
def install_handler (self, handler, back=0):
=== Zope/ZServer/medusa/logger.py 1.15 => 1.16 ===
# pass this either a path or a file object.
def __init__ (self, file, flush=1, mode='a'):
+
+ self.filename = None
+
if type(file) == type(''):
if (file == '-'):
import sys
self.file = sys.stdout
else:
+ self.filename = file
self.file = open (file, mode)
else:
self.file = file
self.do_flush = flush
+ def reopen(self):
+ if self.filename:
+ self.file.close()
+ self.file = open(self.filename,'a')
+
def __repr__ (self):
return '<file logger: %s>' % self.file