Source code for keygrabber.Service

from . import Version
Version.append ('$Revision: 95162 $')
del Version


import ktl
import os
import platform
import resource
import time

try:
    import DFW
except ImportError:
    DFW = None


# The stdiosvc configuration file is common to all keygrabber KTL services.

try:
    reldir = os.environ['RELDIR']
except KeyError:
    stdiosvc = None
else:
    stdiosvc = os.path.join (reldir, 'data', 'keygrabber', 'stdiosvc.conf')


[docs]def startService (main): ''' If the configuration specifies a KTL service, start a DFW backend instance to run the service. ''' if DFW == None: raise ImportError ('DFW module is not available') service = main.config.get ('main', 'service') if service == '': return None if stdiosvc == None: raise RuntimeError ('$RELDIR is not set, cannot locate stdiosvc.conf') setupKeywords.main = main service = DFW.Service (service, stdiosvc, setupKeywords) service['DISPSTA'].set ('ready') return service
def setupKeywords (service): main = setupKeywords.main # The DFW.Keyword subclasses are created here so that they are only # established when DFW is available. class Disconnected (DFW.Keyword.String): def read (self): try: services = ktl.cache () except TypeError: # Not supported in this version of KTL Python. self.period (None) return '' disconnected = [] names = services.keys () names = list (names) names.sort () for name in names: service = services[name] if len (service.descriptors) == 0: disconnected.append (name) disconnected = ' '.join (disconnected) return disconnected class MemoryUsage (DFW.Keyword.Integer): def read (self): resources = resource.getrusage (resource.RUSAGE_SELF) max_usage = resources.ru_maxrss max_usage = str (max_usage) return str (max_usage) class ProcessorUsage (DFW.Keyword.Integer): def __init__ (self, *args, **kwargs): resources = resource.getrusage (resource.RUSAGE_SELF) self.previous_usage = resources.ru_utime + resources.ru_stime self.previous_time = time.time () DFW.Keyword.Integer.__init__ (self, *args, **kwargs) def read (self): resources = resource.getrusage (resource.RUSAGE_SELF) current_usage = resources.ru_utime + resources.ru_stime current_time = time.time () consumed = current_usage - self.previous_usage elapsed = current_time - self.previous_time self.previous_usage = current_usage self.previous_time = current_time if elapsed > 0: usage_percent = 100 * consumed / elapsed usage_percent = int (round (usage_percent)) elif consumed > 0: usage_percent = 100 else: usage_percent = 0 usage_percent = str (usage_percent) return usage_percent class RestartKeyword (DFW.Keyword.Boolean): def __init__ (self, name, service, main): self.main = main DFW.Keyword.Boolean.__init__ (self, name, service) def write (self, value): if value == '1': self.main.start.set () self.main.shutdown.set () class StopKeyword (DFW.Keyword.Boolean): def __init__ (self, name, service, main): self.main = main DFW.Keyword.Boolean.__init__ (self, name, service) def write (self, value): if value == '1': self.main.shutdown.set () class DistributorFunction (DFW.Keyword.Integer): def __init__ (self, name, service, function): self.function = function DFW.Keyword.Integer.__init__ (self, name, service, initial=0, period=1) def read (self): return str (self.function ()) class DistributorValue (DFW.Keyword.Integer): def __init__ (self, name, service, main, attribute): self.distributor = main.distributor self.attribute = attribute DFW.Keyword.Integer.__init__ (self, name, service, initial=0, period=1) def read (self): return str (getattr (self.distributor, self.attribute)) class PendingDBWrites (DistributorFunction): def __init__ (self, service, main): name = 'PENDING_DB' function = main.distributor.database.qsize DistributorFunction.__init__ (self, name, service, function) class PendingLogWrites (DistributorFunction): def __init__ (self, service, main): name = 'PENDING_LOG' function = main.distributor.archive.qsize DistributorFunction.__init__ (self, name, service, function) class TotalInserts (DistributorValue): def __init__ (self, service, main): name = 'INSERTS' attribute = 'insert_count' DistributorValue.__init__ (self, name, service, main, attribute) class TotalUpdates (DistributorValue): def __init__ (self, service, main): name = 'UPDATES' attribute = 'update_count' DistributorValue.__init__ (self, name, service, main, attribute) # Administrivia keywords. DFW.Keyword.Enumerated ('DISPSTA', service, 'initializing') RestartKeyword ('DISPHUP', service, main) StopKeyword ('DISPSTOP', service, main) DFW.Keyword.Integer ('VERSION', service, main.version) # The following keywords will remain static for the duration of # this keygrabber's runtime. hostname = main.config.get ('database', 'hostname') database = main.config.get ('database', 'database') DFW.Keyword.String ('DB_HOST', service, hostname) DFW.Keyword.String ('DB_NAME', service, database) DFW.Keyword.String ('RUNHOST', service, platform.node ()) keyword_count = 0 services = [] for name in main.services: services.append (name) excluded = main.exclude[name] included = main.include[name] if len (included) == 0: keywords = main.services[name].list () else: keywords = included for keyword in keywords: if keyword in excluded: pass else: keyword_count += 1 services.sort () DFW.Keyword.Integer ('KEYWORDS', service, keyword_count) DFW.Keyword.Integer ('SERVICE_COUNT', service, len (services)) DFW.Keyword.String ('SERVICES', service, ' '.join (services)) # This next body of keywords will update periodically with new # values polled from keygrabber itself. Disconnected ('DISCONNECTED', service, initial='', period=1) MemoryUsage ('MEMORY', service, period=1) ProcessorUsage ('PROCESSOR', service, period=1) PendingDBWrites (service, main) PendingLogWrites (service, main) TotalInserts (service, main) TotalUpdates (service, main) # vim: set expandtab tabstop=8 softtabstop=4 shiftwidth=4 autoindent: