Show
Ignore:
Timestamp:
05/22/04 00:02:53 (20 years ago)
Author:
jalet
Message:

Preliminary work on pre-accounting

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/pykota/tool.py

    r1483 r1492  
    2222# 
    2323# $Log$ 
     24# Revision 1.89  2004/05/21 22:02:52  jalet 
     25# Preliminary work on pre-accounting 
     26# 
    2427# Revision 1.88  2004/05/18 14:49:20  jalet 
    2528# Big code changes to completely remove the need for "requester" directives, 
     
    341344import signal 
    342345import socket 
     346import tempfile 
    343347 
    344348from mx import DateTime 
    345349 
    346 from pykota import version, config, storage, logger, accounter 
     350from pykota import version, config, storage, logger, accounter, pdlanalyzer 
    347351 
    348352class PyKotaToolError(Exception): 
     
    757761    def __init__(self) : 
    758762        """Initialize local datas from current environment.""" 
     763        # We begin with ignoring signals, we may de-ignore them later on. 
     764        self.gotSigTerm = 0 
     765        signal.signal(signal.SIGTERM, signal.SIG_IGN) 
     766        signal.signal(signal.SIGCHLD, signal.SIG_IGN) 
     767        signal.signal(signal.SIGPIPE, signal.SIG_IGN) 
     768         
    759769        PyKotaTool.__init__(self) 
    760770        (self.printingsystem, \ 
     
    774784        self.accounter = accounter.openAccounter(self) 
    775785        self.exportJobInfo() 
    776          
    777         # then deal with signals 
    778         # CUPS backends always ignore SIGPIPE and ignore SIGTERM 
    779         # when printing from their stdin 
    780         # Here we have to catch them correctly, and pass 
    781         # SIGTERM to any child if needed. 
    782         self.gotSigTerm = self.gotSigChld = self.gotSigPipe = 0 
    783         signal.signal(signal.SIGTERM, self.sigterm_handler) 
    784         signal.signal(signal.SIGCHLD, self.sigchld_handler) 
    785         signal.signal(signal.SIGPIPE, self.sigpipe_handler) 
    786          
     786        self.jobdatastream = self.openJobDataStream() 
     787        self.softwareJobSize = self.precomputeJobSize() 
     788        self.logdebug("Precomputed job's size is : %s pages" % self.softwareJobSize) 
     789         
     790    def openJobDataStream(self) :     
     791        """Opens the file which contains the job's datas.""" 
     792        if self.preserveinputfile is None : 
     793            # Job comes from sys.stdin, but this is not 
     794            # seekable and complexifies our task, so create 
     795            # a temporary file and use it instead 
     796            self.logdebug("Duplicating data stream from stdin to temporary file") 
     797            MEGABYTE = 1024*1024 
     798            infile = tempfile.TemporaryFile() 
     799            while 1 : 
     800                data = sys.stdin.read(MEGABYTE)  
     801                if not data : 
     802                    break 
     803                infile.write(data) 
     804            infile.flush()     
     805            infile.seek(0) 
     806            return infile 
     807        else :     
     808            # real file, just open it 
     809            self.logdebug("Opening data stream %s" % self.preserveinputfile) 
     810            return open(self.preserveinputfile, "rb") 
     811         
     812    def closeJobDataStream(self) :     
     813        """Closes the file which contains the job's datas.""" 
     814        self.logdebug("Closing data stream.") 
     815        try : 
     816            self.jobdatastream.close() 
     817        except :     
     818            pass 
     819         
     820    def precomputeJobSize(self) :     
     821        """Computes the job size with a software method.""" 
     822        try : 
     823            parser = pdlanalyzer.PDLAnalyzer(self.jobdatastream) 
     824            return parser.getJobSize() 
     825        except pdlanalyzer.PDLAnalyzerError, msg :     
     826            # Here we just log the failure, but 
     827            # we finally ignore it and return 0 since this 
     828            # computation is just an indication of what the 
     829            # job's size MAY be. 
     830            self.logger.log_message(_("Unable to precompute the job's size with the generic PDL analyzer."), "warn") 
     831            return 0 
     832             
    787833    def sigterm_handler(self, signum, frame) : 
    788834        """Sets an attribute whenever SIGTERM is received.""" 
     
    790836        os.putenv("PYKOTASTATUS", "CANCELLED") 
    791837        self.logger.log_message(_("SIGTERM received, job %s cancelled.") % self.jobid, "info") 
    792          
    793     def sigchld_handler(self, signum, frame) : 
    794         """Sets an attribute whenever SIGCHLD is received.""" 
    795         self.gotSigChld = 1 
    796         self.logdebug("SIGCHLD received") 
    797          
    798     def sigpipe_handler(self, signum, frame) : 
    799         """Sets an attribute whenever SIGPIPE is received.""" 
    800         self.gotSigPipe = 1 
    801         self.logdebug("SIGPIPE received") 
    802838         
    803839    def exportJobInfo(self) :