Viewing file: GlobalConfig.py (7.71 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
######################################################################## # $Header: /var/local/cvsroot/4Suite/Ft/Server/Server/GlobalConfig.py,v 1.9 2005/02/27 04:17:31 jkloth Exp $ """ Collected stste from the global 4Suite repository config file, parsed in Ft.Server.Server.Lib.ConfigFile
Copyright 2003 Fourthought, Inc. (USA). Detailed license and copyright information: http://4suite.org/COPYRIGHT Project home, documentation, distributions: http://4suite.org/ """
import sys, os import distutils.util
import Ft from Ft.Server.Server.FtRpc import FtRpcHandler from Ft.Server.Server.Lib import LogUtil from Ft.Server.Server.SCore import GetRepository
DEFAULT_LOG_FILE = 'Logs/error.log' DEFAULT_PID_FILE = 'Logs/4ssd.pid'
# Number of servers to spawn off by default --- also, if fewer than # this free when the caretaker checks, it will spawn more. # Configuration entry: StartServers DEFAULT_START_DAEMON = 5
# Maximum number of *free* server processes --- more than this, and # they will die off. # Configuration entry: MaxSpareServers DEFAULT_MAX_FREE_DAEMON = 10
# Minimum --- fewer than this, and more will be created # Configuration entry: MinSpareServers DEFAULT_MIN_FREE_DAEMON = 5
# Limit on total number of servers running, i.e., limit on the number # of clients who can simultaneously connect --- if this limit is ever # reached, clients will be LOCKED OUT, so it should NOT BE SET TOO LOW. # It is intended mainly as a brake to keep a runaway server from taking # the system with it as it spirals down... # Configuration entry: MaxServers DEFAULT_MAX_DAEMONS = 150
# We keep a hard maximum number of servers --- in case something goes # seriously wrong, we want to stop the fork bomb short of actually # crashing the machine we're running on by filling some kernel table. MAX_DAEMONS = 256
class GlobalConfig: """ The configuration shared between the controller and the individual servers. """
ident = 'Controller'
def __init__(self, username, password, core, filename, debug=0): self.username = username self.password = password self.core = core self.filename = filename self.debug = debug
self.properties = None
self.savedPid = 0 self.pidFile = None self.addresses = []
self.serverRoot = Ft.GetConfigVar('DATADIR')
# Default logging facility (allows logging before config is known) self.logFilename = sys.stderr.name self.logLevel = LogUtil.LOG_WARNING self.errorLog = LogUtil.Logger(self.ident, sys.stderr, self.logLevel)
# Concurrency support self.daemons_to_start = DEFAULT_START_DAEMON # StartServers self.daemons_min_free = DEFAULT_MIN_FREE_DAEMON # MinSpareServers self.daemons_max_free = DEFAULT_MAX_FREE_DAEMON # MaxSpareServers self.max_daemons = DEFAULT_MAX_DAEMONS # MaxServers
#XSLT extensions self.xslt_extension_modules = [] return
def readConfig(self): from Ft.Server.Server.Lib import ConfigFile config_dict = ConfigFile.Read(self.filename) if not self.core in config_dict: sys.stdout.write('The core "%s" (case sensitive) is not defined (%s).\n' % (self.core, config_dict.keys())) return self.properties = config_dict[self.core]
# Break out a few of the values for easy access #pidfile = self.properties.get('PidFile', DEFAULT_PID_FILE) #pidfile = distutils.util.convert_path(pidfile) #self.pidFile = os.path.join(self.serverRoot, pidfile) self.pidFile = self.properties['PidFile']
# This will be an empty list if nothing was in the configuration file. self.addresses = self.properties['ListenAddress'] if not self.addresses: # Defaults to INADDR_ANY self.addresses.append('*')
#logfile = self.properties.get('LogFile', DEFAULT_LOG_FILE) #logfile = distutils.util.convert_path(logfile) #self.logFilename = os.path.join(self.serverRoot, logfile) self.logFilename = self.properties['LogFile']
if self.debug: self.logLevel = LogUtil.LOG_DEBUG elif self.properties.has_key('LogLevel'): self.logLevel = self.properties['LogLevel']
if self.properties.has_key('StartServers'): self.daemons_to_start = self.properties['StartServers']
if self.properties.has_key('MinSpareServers'): self.daemons_min_free = self.properties['MinSpareServers']
if self.properties.has_key('MaxSpareServers'): self.daemons_max_free = self.properties['MaxSpareServers']
if self.properties.has_key('MaxServers'): self.max_daemons = self.properties['MaxServers']
# Don't thrash; make sure at least one spare daemon if self.daemons_max_free < self.daemons_min_free + 1: self.daemons_max_free = self.daemons_min_free + 1
if self.max_daemons > MAX_DAEMONS: self.errorLog.warning('MaxServers of %d exceeds hard limit of %d ' 'servers,\nlowering MaxServers to %d.' % (self.max_daemons, MAX_DAEMONS)) self.max_daemons = MAX_DAEMONS elif self.max_daemons < 1: self.errorLog.warning('Require MaxServers > 0, setting to 1') self.max_daemons = 1
if self.daemons_to_start > self.max_daemons: self.daemons_to_start = self.max_daemons
self.xslt_extension_modules = self.properties['XsltExtensionModule'] return
def openLogs(self): if self.debug: # Redirect our logging to stderr and force debug maxlevel self.errorLog = LogUtil.Logger(self.ident, sys.stderr, self.logLevel) else: self.errorLog = LogUtil.Logger(self.ident, self.logFilename, self.logLevel, showPid=1) # Redirect our standard streams to the log file sys.stdout = LogUtil.StreamLogger(self.errorLog, LogUtil.LOG_DEBUG) sys.stderr = LogUtil.StreamLogger(self.errorLog, LogUtil.LOG_ERROR) return
def getRepository(self): return GetRepository(self.username, self.password, self.errorLog, self.properties)
# -- process control ---------------------------------------------
def savePid(self): mypid = os.getpid() if os.path.exists(self.pidFile) and self.savedPid != mypid: self.errorLog.warning('PID file %s overwritten -- unclean ' 'shutdown of previous run?' % self.pidFile) try: fd = open(self.pidFile, 'w') except Exception, error: self.errorLog.critical("Unable to open pid file '%s': %s\n" % (self.pidFile, str(error))) sys.exit(1)
try: fd.write(str(mypid)) except Exception, error: self.errorLog.critical("Unable to write to pid file '%s': %s\n" % (self.pidFile, str(error))) try: fd.close() except: self.errorLog.error("Error closing file descriptor\n") sys.exit(1)
try: fd.close() except: self.errorLog.error("Error closing file descriptor\n") sys.exit(1)
self.savedPid = mypid return
def removePid(self): try: if os.path.exists(self.pidFile): os.remove(self.pidFile) self.errorLog.info('removed PID file %s' % self.pidFile) except: self.errorLog.debug('Unable to remove file: %s' % self.pidFile) return
|