Commit 7888effd authored by Sidnei da Silva's avatar Sidnei da Silva

* Implement a signal mechanism for Windows utilising Windows 'Named Events'.

  See comments in WinSignalHandler.py for details.
* As Windows can not rename an open file, when the 'reopen' signal is
  received try and call a 'rotate' method rather than a reopen.  Rotation
  itself is implemented in zLOG.LogHandler
parent f40df82e
...@@ -18,14 +18,23 @@ $Id$ ...@@ -18,14 +18,23 @@ $Id$
__version__='$Revision: 1.3 $'[11:-2] __version__='$Revision: 1.3 $'[11:-2]
import logging import logging
import sys import sys, os
import Lifetime import Lifetime
from SignalHandler import SignalHandler
logger = logging.getLogger("Z2") logger = logging.getLogger("Z2")
if os.name == 'nt':
try:
from WinSignalHandler import SignalHandler
except ImportError:
msg = ('Can not install signal handlers. Please install '
'(or upgrade) your pywin32 installation '
'(https://sf.net/projects/pywin32)')
logger.warning(msg)
SignalHandler = None
else:
from SignalHandler import SignalHandler
def shutdownFastHandler(): def shutdownFastHandler():
"""Shutdown cleanly on SIGTERM. This is registered first, """Shutdown cleanly on SIGTERM. This is registered first,
...@@ -60,6 +69,24 @@ class LogfileReopenHandler: ...@@ -60,6 +69,24 @@ class LogfileReopenHandler:
log.reopen() log.reopen()
logger.info("Log files reopened successfully") logger.info("Log files reopened successfully")
# On Windows, a 'reopen' is useless - the file can not be renamed
# while open, so we perform a trivial 'rotate'.
class LogfileRotateHandler:
"""Rotate log files on SIGUSR2. Only called on Windows. This is
registered first, so it should be called after all other SIGUSR2
handlers."""
def __init__(self, loggers):
self.loggers = [log for log in loggers if log is not None]
def __call__(self):
logger.debug("Log files rotation starting...")
for log in self.loggers:
for f in log.handler_factories:
handler = f()
if hasattr(handler, 'rotate') and callable(handler.rotate):
handler.rotate()
logger.info("Log files rotation complete")
def packHandler(): def packHandler():
""" Packs the main database. Not safe to call under a signal """ Packs the main database. Not safe to call under a signal
handler, because it blocks the main thread """ handler, because it blocks the main thread """
...@@ -74,14 +101,32 @@ def packHandler(): ...@@ -74,14 +101,32 @@ def packHandler():
def registerZopeSignals(loggers): def registerZopeSignals(loggers):
import signal from signal import SIGTERM, SIGINT
SignalHandler.registerHandler(signal.SIGTERM, shutdownFastHandler) try:
SignalHandler.registerHandler(signal.SIGINT, shutdownHandler) from signal import SIGHUP, SIGUSR1, SIGUSR2
SignalHandler.registerHandler(signal.SIGHUP, restartHandler) except ImportError:
SignalHandler.registerHandler(signal.SIGUSR2, # Windows doesn't have these (but also doesn't care what the exact
LogfileReopenHandler(loggers)) # numbers are)
SIGHUP = 1
SIGUSR1 = 10
SIGUSR2 = 12
if not SignalHandler:
return
SignalHandler.registerHandler(SIGTERM, shutdownFastHandler)
SignalHandler.registerHandler(SIGINT, shutdownHandler)
if os.name != 'nt':
SignalHandler.registerHandler(SIGHUP, restartHandler)
SignalHandler.registerHandler(SIGUSR2, LogfileReopenHandler(loggers))
else:
# no restart handler on windows.
# Log files get 'rotated', not 'reopened'
SignalHandler.registerHandler(SIGUSR2, LogfileRotateHandler(loggers))
# SIGUSR1 is nominally reserved for pack, but we dont have an # SIGUSR1 is nominally reserved for pack, but we dont have an
# implementation that is stable yet because if the signal handler # implementation that is stable yet because if the signal handler
# fires it will be caught in the main thread and all network operations # fires it will be caught in the main thread and all network operations
# will cease until it's finished. # will cease until it's finished.
#SignalHandler.registerHandler(signal.SIGUSR1, packHandler) # (The above is *not* True for Windows - a different thread is used to
# catch the signals. This probably could be switched on for Windows
# if anyone cares)
#SignalHandler.registerHandler(SIGUSR1, packHandler)
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment