import ThreadPool from constants import constants from Logger import Logger import threading class Scheduler(object): lock=threading.Lock() listOfAlreadyBuiltPackages=[] listOfPackagesToBuild=[] listOfPackagesCurrentlyBuilding=[] sortedList=[] listOfPackagesNextToBuild=[] listOfFailedPackages=[] logger=None event=None stopScheduling=False @staticmethod def setEvent(event): Scheduler.event=event @staticmethod def setLog(logName,logPath): Scheduler.logger = Logger.getLogger(logName, logPath) @staticmethod def setParams(sortedList,listOfAlreadyBuiltPackages): Scheduler.sortedList=sortedList Scheduler.listOfAlreadyBuiltPackages=listOfAlreadyBuiltPackages for x in Scheduler.sortedList: if x not in Scheduler.listOfAlreadyBuiltPackages or x in constants.testForceRPMS: Scheduler.listOfPackagesToBuild.append(x) Scheduler.listOfPackagesCurrentlyBuilding=[] Scheduler.listOfPackagesNextToBuild=[] Scheduler.listOfFailedPackages=[] @staticmethod def getRequiredPackages(package): listRequiredRPMPackages=[] listRequiredRPMPackages.extend(constants.specData.getBuildRequiresForPackage(package)) listRequiredRPMPackages.extend(constants.specData.getRequiresAllForPackage(package)) listRequiredPackages=[] for pkg in listRequiredRPMPackages: basePkg=constants.specData.getSpecName(pkg) if basePkg not in listRequiredPackages: listRequiredPackages.append(basePkg) return listRequiredPackages @staticmethod def __getListNextPackagesReadyToBuild(): listOfPackagesNextToBuild=[] Scheduler.logger.info("Checking for next possible packages to build") for pkg in Scheduler.listOfPackagesToBuild: if pkg in Scheduler.listOfPackagesCurrentlyBuilding: continue listRequiredPackages=Scheduler.getRequiredPackages(pkg) canBuild=True Scheduler.logger.info("Required packages for "+ pkg + " are:") Scheduler.logger.info(listRequiredPackages) for reqPkg in listRequiredPackages: if reqPkg not in Scheduler.listOfAlreadyBuiltPackages: canBuild=False Scheduler.logger.info(reqPkg+" is not available. So we cannot build "+ pkg +" at this moment.") break if canBuild: listOfPackagesNextToBuild.append(pkg) Scheduler.logger.info("Adding "+ pkg +" to the schedule list") return listOfPackagesNextToBuild @staticmethod def getNextPackageToBuild(): Scheduler.logger.info("Waiting to acquire scheduler lock") Scheduler.lock.acquire() if Scheduler.stopScheduling: Scheduler.logger.info("Released scheduler lock") Scheduler.lock.release() return None if len(Scheduler.listOfPackagesToBuild) == 0: if Scheduler.event is not None: Scheduler.event.set() if len(Scheduler.listOfPackagesNextToBuild) == 0: listOfPackagesNextToBuild=Scheduler.__getListNextPackagesReadyToBuild() Scheduler.listOfPackagesNextToBuild=listOfPackagesNextToBuild if len(Scheduler.listOfPackagesNextToBuild) == 0: Scheduler.logger.info("Released scheduler lock") Scheduler.lock.release() return None package=Scheduler.listOfPackagesNextToBuild.pop(0) if len(Scheduler.listOfPackagesNextToBuild) > 0: ThreadPool.ThreadPool.activateWorkerThreads(len(Scheduler.listOfPackagesNextToBuild)) Scheduler.logger.info("Released scheduler lock") Scheduler.lock.release() Scheduler.listOfPackagesCurrentlyBuilding.append(package) Scheduler.listOfPackagesToBuild.remove(package) return package #can be synchronized TODO @staticmethod def notifyPackageBuildCompleted(package): if package in Scheduler.listOfPackagesCurrentlyBuilding: Scheduler.listOfPackagesCurrentlyBuilding.remove(package) Scheduler.listOfAlreadyBuiltPackages.append(package) #can be synchronized TODO @staticmethod def notifyPackageBuildFailed(package): if package in Scheduler.listOfPackagesCurrentlyBuilding: Scheduler.listOfPackagesCurrentlyBuilding.remove(package) Scheduler.listOfFailedPackages.append(package) @staticmethod def isAllPackagesBuilt(): if len(Scheduler.listOfPackagesToBuild) == 0 : return True return False @staticmethod def isAnyPackagesFailedToBuild(): if len(Scheduler.listOfFailedPackages) != 0: return True return False