[Zope-Checkins] CVS: Zope/lib/python/Signals - SignalHandler.py:1.1.30.1 Signals.py:1.1.30.1 __init__.py:1.1.30.1
Chris McDonough
chrism@zope.com
Mon, 25 Nov 2002 22:10:39 -0500
Update of /cvs-repository/Zope/lib/python/Signals
In directory cvs.zope.org:/tmp/cvs-serv25870
Added Files:
Tag: chrism-install-branch
SignalHandler.py Signals.py __init__.py
Log Message:
Recommit signals to chrism-install-branch.,
=== Added File Zope/lib/python/Signals/SignalHandler.py ===
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Signal handling dispatcher."""
__version__='$Revision: 1.1.30.1 $'[11:-2]
import sys, os
import signal, zLOG
class SignalHandler:
def __init__(self):
self.registry = {}
def registerHandler(self, signum, handler):
"""Register a handler function that will be called when the process
recieves the signal signum. The signum argument must be a signal
constant such as SIGTERM. The handler argument must be a function
or method that takes no arguments. Note that handlers will not
be called on non-posix platforms."""
if os.name != 'posix':
return
items = self.registry.get(signum)
if items is None:
items = self.registry[signum] = []
signal.signal(signum, self.signalHandler)
signame = get_signal_name(signum)
zLOG.LOG('Z2', zLOG.BLATHER, "Installed sighandler for %s" % (
signame
))
items.insert(0, handler)
def getRegisteredSignals(self):
"""Return a list of the signals that have handlers registered. This
is used to pass the signals through to the ZDaemon code."""
return self.registry.keys()
def signalHandler(self, signum, frame):
"""Meta signal handler that dispatches to registered handlers."""
signame = get_signal_name(signum)
zLOG.LOG('Z2', zLOG.INFO , "Caught signal %s" % signame)
for handler in self.registry.get(signum, []):
# Never let a bad handler prevent the standard signal
# handlers from running.
try: handler()
except SystemExit:
# if we trap SystemExit, we can't restart
raise
except:
zLOG.LOG('Z2', zLOG.WARNING,
'A handler for %s failed!' % signame,
error=sys.exc_info())
_signals = None
def get_signal_name(n):
"""Return the symbolic name for signal n.
Returns 'unknown' if there is no SIG name bound to n in the signal
module.
"""
global _signals
if _signals is None:
_signals = {}
for k, v in signal.__dict__.items():
startswith = getattr(k, 'startswith', None)
if startswith is None:
continue
if startswith('SIG') and not startswith('SIG_'):
_signals[v] = k
return _signals.get(n, 'unknown')
# The SignalHandler is actually a singleton.
SignalHandler = SignalHandler()
=== Added File Zope/lib/python/Signals/Signals.py ===
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""
Zope signal handlers for clean shutdown, restart and log rotation.
$Id: Signals.py,v 1.1.30.1 2002/11/26 03:10:38 chrism Exp $
"""
__version__='$Revision: 1.1.30.1 $'[11:-2]
from SignalHandler import SignalHandler
import zLOG
import sys
import Lifetime
def shutdownFastHandler():
"""Shutdown cleanly on SIGTERM. This is registered first,
so it should be called after all other handlers."""
zLOG.LOG('Z2', zLOG.INFO , "Shutting down fast")
Lifetime.shutdown(0,fast=1)
def shutdownHandler():
"""Shutdown cleanly on SIGINT. This is registered first,
so it should be called after all other handlers."""
zLOG.LOG('Z2', zLOG.INFO , "Shutting down")
sys.exit(0)
def restartHandler():
"""Restart cleanly on SIGHUP. This is registered first, so it
should be called after all other SIGHUP handlers."""
zLOG.LOG('Z2', zLOG.INFO , "Restarting")
Lifetime.shutdown(1)
def logfileReopenHandler():
"""Reopen log files on SIGUSR2. This is registered first, so it
should be called after all other SIGUSR2 handlers."""
zLOG.LOG('Z2', zLOG.INFO , "Reopening log files")
reopen = getattr(getattr(sys, '__lg', None), 'reopen', None)
if reopen is not None:
reopen()
zLOG.LOG('Z2', zLOG.BLATHER, "Reopened access log")
reopen = getattr(getattr(sys, '__detailedlog', None), 'reopen', None)
if reopen is not None:
reopen()
zLOG.LOG('Z2', zLOG.BLATHER,"Reopened detailed request log")
zLOG.initialize()
zLOG.LOG('Z2', zLOG.BLATHER, "Reopened event log")
zLOG.LOG('Z2', zLOG.INFO, "Log files reopened successfully")
def packHandler():
""" Packs the main database. Not safe to call under a signal
handler, because it blocks the main thread """
zLOG.LOG('Z2', zLOG.INFO, 'Packing main ZODB database')
import Globals
try:
db = Globals.opened[0]
db.pack()
zLOG.LOG('Z2', zLOG.INFO,
'Database packing launched or completed successfully')
except:
zLOG.LOG('Z2', zLOG.INFO,
'Call to pack failed!', error=sys.exc_info())
def registerZopeSignals():
import signal
SignalHandler.registerHandler(signal.SIGTERM, shutdownFastHandler)
SignalHandler.registerHandler(signal.SIGINT, shutdownHandler)
SignalHandler.registerHandler(signal.SIGHUP, restartHandler)
SignalHandler.registerHandler(signal.SIGUSR2, logfileReopenHandler)
# SIGUSR1 is nominally reserved for pack, but we dont have an
# implementation that is stable yet because if the signal handler
# fires it will be caught in the main thread and all network operations
# will cease until it's finished.
#SignalHandler.registerHandler(signal.SIGUSR1, packHandler)
=== Added File Zope/lib/python/Signals/__init__.py ===
"""
Signals package __init__.py
"""