root/branches/eam_branches/ipp-20121219/ippToPsps/jython/ipptopsps.py @ 34970

Revision 34970, 5.8 KB (checked in by eugene, 6 years ago)

strip absolute path from classfile (eg, queue.py), add / to end of configDir (if not None); pass configDir to Config

Line 
1#!/usr/bin/env jython
2
3import signal
4import sys
5import os
6import time
7import logging
8import socket
9
10from config import Config
11from pslogger import PSLogger
12from ipptopspsdb import IppToPspsDb
13
14'''
15Abstract base class for all ippToPsps programs
16Handles command-line args, setting up of Config and logger objects, clean exiting etc
17'''
18class IppToPsps(object):
19
20    '''
21    Constructor
22    '''
23    def __init__(self, argv, logToStdout=1, logToFile=0):
24
25        # are the arsg ok? all programs require a config name
26        if len(sys.argv) < 2: 
27            self.printUsage()
28            self.exitProgram("Wrong args")
29
30        # some class constants
31        self.PROGNAME = os.path.basename(sys.argv[0])
32        CONFIGNAME = sys.argv[1]
33        self.HOST = socket.gethostname()
34        self.PID = os.getpid()
35        self.PAUSEPERIOD = 60
36        self.HOURS = None
37        self.MINUTES = None
38        self.SECONDS = None
39
40        self.configDir = os.getenv("IPPTOPSPS_DATA")
41        if self.configDir is not None:
42            self.configDir = self.configDir + "/"
43
44        self.createNewConfig = False
45        self.rotateConfigs = False
46        # a new config?
47        if CONFIGNAME == "edit": self.createNewConfig = True
48        # should we rotate configs for this program?
49        elif CONFIGNAME == "all": self.rotateConfigs = True
50
51        # set up config object
52        self.config = Config(self.PROGNAME, CONFIGNAME, self.configDir)
53        self.logger = self.config.getLogger(self.HOST, self.PID, logToStdout, logToFile)
54
55        # create connection to databases database
56        try:
57            self.ippToPspsDb = IppToPspsDb(self.logger, self.config)
58        except:
59            self.exitProgram("Could not connect to ipptopsps Db")
60            raise
61
62        self.checkClientStatus()
63
64        # catch Ctrl-C signal
65        signal.signal(signal.SIGINT, self.signal_handler)
66
67        # title for log
68        self.logger.infoSeparator()
69        self.logger.infoTitle("ippToPsps '" + self.PROGNAME + "' started")
70        self.logger.infoPair("Host", self.HOST)
71        self.logger.infoPair("PID", "%d" % self.PID)
72        self.logger.infoPair("Config", self.config.name)
73
74    '''
75    Parses a poll-time argument string and stored as class variables
76    '''
77    def parsePollTimeArg(self, hours):
78
79        try:
80            self.HOURS = float(hours)
81            self.MINUTES = self.HOURS * 60.0
82            self.SECONDS = self.MINUTES * 60.0
83        except:
84            pass
85
86    '''
87    Waits for user defined poll time
88    '''
89    def waitForPollTime(self):
90
91        # if not POLL time set, then return False
92        if not self.SECONDS: return False
93
94        if self.HOURS < 1.0:
95            str = "%.1f minutes" % self.MINUTES
96        else:
97            str = "%.1f hours" % self.HOURS
98
99        self.logger.infoPair("Waiting for", str)
100        time.sleep(self.SECONDS)
101
102        return True
103
104    '''
105    Prints usage to stdout
106    '''
107    def printUsage(self, extra=""):
108
109        # write message to log or stdout if no logger set up
110        msg = sys.argv[0] + " <configName|all|edit> " + extra
111        try:
112            self.logger.errorPair("Usage:", msg)
113        except: 
114            print "*** Usage: " + msg
115
116    '''
117    Refreshes the config then recreates objects with new settings
118    '''
119    def refreshConfig(self):
120
121        # new config?
122        if self.createNewConfig: 
123            self.ippToPspsDb.editConfig()
124            self.ippToPspsDb.setConfigForThisClient(self.config.name, self.HOST, self.PID)
125            self.createNewConfig = False
126
127        # if we are rotating configs, then look for next active one in list
128        if self.rotateConfigs:
129            self.ippToPspsDb.getConfigForThisClient(self.HOST, self.PID)
130            configs = self.ippToPspsDb.getActiveConfigList()
131             
132            i = 1
133            for config in configs:
134               if config == self.config.name: break
135               i += 1
136
137            if i >= len(configs): newConfig = configs[0]
138            else: newConfig = configs[i]
139
140            self.ippToPspsDb.setConfigForThisClient(newConfig, self.HOST, self.PID)
141
142        return self.ippToPspsDb.readConfig(self.HOST, self.PID)
143
144    '''
145    All implementing subclasses (programs) should call this method once in a while to see if it should be paused or killed, otherwise this updates the clients table with current time and reloads the config data
146    '''
147    def checkClientStatus(self):
148
149        self.ippToPspsDb.updateClient(self.PROGNAME, self.HOST, self.PID)
150
151        if self.ippToPspsDb.isKilled(self.HOST, self.PID): 
152            self.exitProgram("killed via Db")
153       
154        # this loop pauses the process if we have no config or we have set it to pause
155        firstTimeIn = True
156        while not self.refreshConfig() or self.ippToPspsDb.isPaused(self.HOST, self.PID):
157
158            self.ippToPspsDb.updateClient(self.PROGNAME, self.HOST, self.PID)
159            if self.ippToPspsDb.isKilled(self.HOST, self.PID): 
160                self.exitProgram("killed while paused")
161            if firstTimeIn: self.logger.infoPair("Paused. Will check again every", "%d secs" % self.PAUSEPERIOD)
162            firstTimeIn = False
163            time.sleep(self.PAUSEPERIOD)
164
165
166    '''
167    Handler for Ctrl-C signal
168    '''
169    def signal_handler(self, signal, frame):
170
171       self.exitProgram("Ctrl-C")
172
173
174    '''
175    Exits the program cleanly, removes info from ipptopsps database
176    '''
177    def exitProgram(self, exitReason="quit"):
178
179        # write message to log or stdout if no logger set up
180        try:
181            self.logger.infoPair(self.PROGNAME + " exited", exitReason)
182        except: 
183            print "*** Program exited: " + exitReason
184
185        # remove from database if possible
186        try:
187            self.ippToPspsDb.removeClient(self.HOST, self.PID)
188        except:
189            pass
190
191        sys.exit(0)
192   
193
Note: See TracBrowser for help on using the browser.